Luminusのドキュメントのdeploymentの節( http://www.luminusweb.net/docs/deployment.md )の勝手な和訳。
2016年02月28日時点の内容に基いています。
原文の最新のソースは: https://github.com/luminus-framework/luminus/blob/master/resources/md/deployment.md
Deployment
Contents
- Running Standalone
- Deploying on Immutant App Server
- Deploying to Tomcat
- VPS Deployment
- Application deployment
- Fronting with Nginx
- Setting up SSL
- Heroku Deployment
- Enabling nREPL
Running Standalone
アプリケーションをスタンドアローンで実行できるようにするには、単純にこう実行すればOKです。
lein uberjar
出来上がったjar
はtarget
フォルダにあります。次のように実行できます。
java -jar myapp.jar
デフォルトでは、スタンドアローンのアプリケーションは、起動に組み込みのImmutantサーバを使用します。しかしながら、例えば+jetty
などのprofileを使ったとしたら、代わりに別のサーバが使用されます。独自のポート番号を指定するには$PORT
環境変数をセットする必要があります。例をあげると:
export PORT=8080
java -jar myapp.jar
Deploying on Immutant App Server
Immutantアプリケーションサーバのデプロイについては、Immutantの公式のドキュメントで概略されているステップをなぞってみてください。Linodeにも、Ubuntu14.04上でImmutantとWildFlyを使ったLuminusアプリケーションのデプロイの仕方についての手引きがあります。
Deploying to Tomcat
Apache Tomcat のようなコンテナにアプリケーションをデプロイするためにはWAR形式のアーカイブを生成する必要があります。これは、+war
profileを使用すると同梱されるlein-uberwarプラグインだけがサポートしています。
lein-uberwar
プラグインを有効にするには、project.clj
ファイルに次の設定を手動で追加してください。
:plugins [...
[lein-uberwar "0.1.0"]]
:uberwar {:handler <app>.handler/app
:init <app>.handler/init
:destroy <app>.handler/destroy
:name "<app>.war"}
WARを作成するためにアプリケーションをパッケージすることができます。こう実行します。
lein uberwar
次に、生成された<app>.war
を単純にTomcatのwebapps
フォルダにコピーすればOKです。例えば:
cp target/<app>.war ~/tomcat/webapps/
すると、あなたのアプリケーションはTomcatを起動したときに/<app>
コンテキストで利用可能になります。アプリケーションをルート・コンテキストにデプロイしたかったら、単にwebapp
配下にWARをROOT.war
という名前にしてコピーすればOKです。
VPS Deployment
DigitalOceanのような仮想プライベート・サーバ(VPS)は、Clojureアプリケーション向けの安価なホスティング・オプションを提供しています。あなたのDigitalOceanサーバをセットアップするにはこの手引きにとおりやってください。いったんサーバが作成されると、ここに書かれているようにUbuntuをインストールすることができます。最終的に、この手順に従ってあなたのUbuntuにjavaをインストールします。以降で示す手順は、Ubuntu15.04かそれより新しいバージョンに対応しています。
Application deployment
このステップでは、サーバにあなたのアプリケーションをデプロイし、サーバを起動すると自動でアプリケーションが開始することを確認します。これを実現するのにsystemd
を使用します。あなたのアプリケーションを実行するdeploy
ユーザをを作成してください。
sudo adduser -m deploy
sudo passwd -l deploy
あなたのアプリケーション用に、サーバ上に/var/myapp
のようなディレクトリを作成してください。そして、scp
を使ってサーバにアプリケーションをアップロードしてください。
$ scp myapp.jar user@<domain>:/var/myapp/
ここまできたら、アプリケーションが起動可能か一度テストしてみるべきです。ssh
を使ってサーバに接続し、アプリケーションを実行します。
java -jar /var/myapp/myapp.jar
もし全てうまくいっていると、アプリケーションはローカルで起動します。次のコマンドでアプリケーションが期待通り動いているか確認します。
curl http://127.0.0.1:3000/
あなたのアプリケーションは、今やサーバ上でhttp://<domain>:3000
でアクセスすることも可能です。もし、アプリケーションがアクセスできなかったら、ファイヤーウォールがこのポートのアクセスを許可しているか確認してください。あなたが利用しているVPSのプロバイダによっては、3000番ポートに対するアクセス・ポイントを作成する必要があるかもしれません。
ここで、アプリケーションのインスタンスを一度停止して、アプリケーションのライフサイクルを管理するsystemd
の設定を作成しましょう。とりわけ、サーバ起動時にアプリケーションが開始することに注意しましょう。/lib/systemd/system/myapp.service
というファイルを作成し、中身を次のとおりにします。
[Unit]
Description=My Application
After=network.target
[Service]
WorkingDirectory=/var/myapp
EnvironmentFile=-/var/myapp/env
Environment="DATABASE_URL=jdbc:postgresql://localhost/app?user=app_user&password=secret"
ExecStart=/usr/bin/java -jar /var/myapp/myapp.jar
User=deploy
[Install]
WantedBy=multi-user.target
デフォルトのJVMはかなりアグレッシブなメモリの使い方をすることに注意してください。もしJVMが使うメモリの量を減らしたかったら、 次の1行を[Service]
設定に追加することができます。
[Service]
...
_JAVA_OPTIONS="-Xmx256m"
ExecStart=/usr/bin/java -jar /var/myapp/myapp.jar
この設定は、JVMに使用を許可するメモリの最大量を制限します。ここまでくると、次のコマンドで、システムに再起動がかかるたびに毎回アプリケーションを開始するようにsystemd
に伝えることができます。
sudo systemctl daemon-reload
sudo systemctl enable myapp.service
システムが再起動するとき、あなたのアプリケーションは開始しリクエストを処理する準備が整います。テストしたくなるんじゃないでしょうか。単純にあなたのマシンを再起動し、プロセスを確認してください。
ps -ef | grep java
このコマンドを実行すると、何かこんな感じのを返します。UID
に注目してください。これがdeploy
になっているべきです。root
のままになっていたら重大なセキュリティ・リスクになってしまうでしょう。
deploy 730 1 1 06:45 ? 00:00:42 /usr/bin/java -jar /var/mysite/mysite.jar
Fronting with Nginx
次のコマンドでNginxをインストールしてください。
$ sudo apt-get install nginx
次に、/etc/nginx/sites-available/default
にデフォルトの設定のバックアップを行って、それをあなたのアプリケーション独自の設定ファイルに置き換えてください。例えばこんなふうに:
server{
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name localhost mydomain.com www.mydomain.com;
access_log /var/log/myapp_access.log;
error_log /var/log/myapp_error.log;
location / {
proxy_pass http://localhost:3000/;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
}
こう実行してNginxを再起動してください。
sudo service nginx restart
それから、アプリケーションがhttp://<domain>
で利用可能なことをテストしてください。
追加で、アプリケーションの静的リソースをNginxに配布させるように設定することもできます。これをやるには、全ての静的リソースがstatic
などの共通の接頭辞を使って配信されることを保証しなければいけません。次に、プロジェクトのフォルダで次のようなコマンドを実行して、resources/public/static
フォルダをアプリケーションからサーバ上の/var/myapp/static
などの場所にアップロードしてください。
scp -r resources/public/static user@<domain>:/var/myapp/static
次の追加設定オプションを、Nginxの設定のserver
セクション以下に追記してください。
location /static/ {
alias /var/myapp/static/;
}
http://<domain>/static
へのあらゆるリクエストについて、あなたのアプリケーションを迂回しその代わりに直接配信するようにNginxさせます。
圧縮を有効にするために、次の設定があなたの/etc/nginx/nginx.conf
に存在することを確かめてください。
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;">
Setting up SSL
もしあなたのサイトがなんらかのユーザ認証を行うなら、HTTPSを使いたいでしょう。まず必要なのは、SSL証明書とその鍵です。この2つをそれぞれcert.crt
とcert.key
と呼びます。
Setting up SSL Certificate using Let's Encrypt
インストール・ツールをダウンロードし、次のコマンドで証明書を生成してください。
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
/letsencrypt-auto certonly --email <you@email.com> -d <yoursite.com> -d <www.yoursite.com> --webroot --webroot-path /var/www/html
追加で、証明書を自動で更新するためにCronのジョブをセットアップしてください。root
でこう実行することでcrontabが更新できます。
su
crontab -e
次の1行を追加してください。
0 0 1,15 * * /path-to-letsencrypt/letsencrypt-auto certonly --keep-until-expiring --email <you@email.com> -d <yoursite.com> -d <www.yoursite.com> --webroot --webroot-path /var/www/html
OpenSSLのデフォルトを使用する代わりに、より強力なDHEパラメータを生成しましょう。これは、鍵交換に1024-bitの鍵を込めます。
cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096
次に、/etc/nginx/sites-available/default
内の設定を次のように更新したくなるでしょう。
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name localhost mydomain.com www.mydomain.com;
ssl_certificate /etc/letsencrypt/live/<yoursite.com>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<yoursite.com>/privkey.pem;
ssl on;
ssl_prefer_server_ciphers on;
ssl_session_timeout 180m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'AES256+EECDH:AES256+EDH';
ssl_dhparam /etc/ssl/certs/dhparam.pem;
add_header Strict-Transport-Security 'max-age=31536000';
access_log /var/log/myapp_access.log;
error_log /var/log/myapp_error.log;
location / {
proxy_set_header Host $host;
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;
# Fix the “It appears that your reverse proxy set up is broken" error.
proxy_pass http://localhost:3000;
proxy_read_timeout 90;
proxy_redirect http://localhost:3000 https://mydomain.com;
}
}
上記の設定はNginxに、HTTPのリクエストをHTTPSにリダイレクトし、配信でさっきの証明書を使用するにようにさせます。
最終的に、次のコマンドを実行することによって、特定のポートだけを許可するようにファイヤー・ウォールを設定してください。
$ sudo ufw allow ssh
$ sudo ufw allow http
$ sudo ufw allow https
$ sudo ufw enable
SSL Server Testを使用すれば、SSLの設定をテストすることができます。
Heroku Deployment
まず、GitとHeroku toolbeltがインストールされているか確認し、以下のステップに従ってください。
やりたかったらで良いですが、アプリケーションがローカルで起動することをテストしてみてください。こうすればOKです。
heroku local
ここまできたら、あならのgitリポジトリを初期化し、アプリケーションのコードをコミットすることができます。
git init
git add .
git commit -m "init"
Herokuにあなたのappを作成
heroku create
任意で、アプリケーションで使うデータベースを作成
heroku addons:create heroku-postgresql
接続設定は、appのadd-ons配下のHeroku dashboardにあります。
アプリケーションをデプロイ
git push heroku master
これで、あなたのアプリケーションはHerokuにデプロイできるはずだ。データベースを更新または初期化するために
heroku run lein run migrate
さらなる手順は、公式ドキュメントを見てください。
Enabling nREPL
LuminusはサーバのREPLに接続することを可能にするnREPLのセットアップを備えています。この機能は、稼働中のアプリケーションをhotfixするだけでなくデバッグ全般に便利です。nREPLのサポートを有効にするには、NREPL_PORT
環境変数に利用したいポート番号を設定します。
export NREPL_PORT=7000
REPLの接続をテストするなら、単に次のコマンドを実行してください。
lein repl :connect 7001
ローカルのREPLに接続するのと全く同じようにして、好きなIDEからリモートのREPLに接続することができます。
リモートのサーバでnREPLを起動するとき、SSHを使ってローカル・マシンにREPLのポートをフォワードすることをおすすめします。
ssh -L 7001:localhost:7001 remotehost