読者です 読者をやめる 読者になる 読者になる

Sqaleハック Gunicornを使ってPython/Djangoを動かす

Sqale『無料アプリケーション1個 プレゼント』キャンペーン実施中! というのをやっていたのでSqaleに申し込んでアプリを作ってみた。

Ruby/Rackのみをサポートしているとのことだったけど、ドキュメントを読んでみたらサーバーにSSHログインして弄れるようなのでいろいろできそうだと思った。

nginx->unicornの構成で動いているみたい。

# /etc/supervisor.d/app.conf
[program:app]
command=/opt/sqale/bin/bundle-exec-app

unicorn自体はsupervisorで見張ってた。

/opt/sqale 以下にランタムみたいなものを発見

ls /opt/sqale/bin/
  app  bundle-exec-app  bundle-exec-foreman  bundle-exec-unicorn  bundle-exec.functions  rake  restart-unicorn  restart-unicorn-worker

nginxの設定を見る

# /etc/nginx/nginx.conf
user sqale sqale;

サーバープロセスがこのログインユーザーで動いてるのか〜というのを見てピンとくる

/etc/init.d/nginx stop
  httpd: stopped

とまってしまった。わりとsqaleユーザー権限強い(/etc 以下などは弄れない)。

upstream unicorn {
    server unix:/var/run/app/app.sock;
}

unicornUNIXドメインソケットを受け取っているのでこれを任意のサーバーのものに変えてしまえばよさそう

ls -la /var/run/app/
  total 4
  drwxr-xr-x 2 sqale sqale    6 Mar 13 00:25 .

いじれそう

とりあえず、Unicornは停止

/etc/init.d/app stop

Djangoインストール

wget https://raw.github.com/pypa/virtualenv/develop/virtualenv.py
python virtualenv.py venv
./venv/bin/pip install django gunicorn MySQLdb
./venv/bin/django-admin.py startproject project
./venv/bin/python project/manage.py startapp app
./venv/bin/python project/manage.py syncdb
# project/project/settings.py

# MySQLの設定
# Sqale ダッシュボードで確認できる
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'sqale_359094befb',
        'USER': 'sqale_359094befb',
        'PASSWORD': '***',
        'HOST': 'mysql001.sqale.jp',
    }
}

# manage.py からgnucorn起動できるようにする
INSTALLED_APPS = (
    # 追加
    'gunicorn',
    'app',
)

# 静的ファイルはnginxで配信しているのでパスを指定しないといけない
STATICFILES_DIRS = (
    '/home/sqale/current/public',
)


サーバー起動

./venv/bin/python project/manage.py run_gunicorn -w 1 -b unix:/var/run/app/app.sock

ブラウザから確認

実際に動かしてるのがこれ

http://laiso-laiso.sqale.jp/admin/ (admin:sqale でログインできる)
停止しました

unicornと違ってsupervisorに監視されてないので落ちたら気付かないし、非公式な方法なので運営は無理だと思う。

おまけ Unicorn 起動時に任意のRubyコード実行 / Unicornの設定ファイルを乗っとる

# /opt/sqale/bin/bundle-exec-unicorn
exec bundle exec unicorn -c /etc/unicorn/config.rb -E production
which bundle
  ~/.rbenv/shims/bundle

rbenv which unicorn 
/home/sqale/.rbenv/versions/1.9.3-p327/bin/unicorn

ls -la ~/.rbenv/versions/ 
  total 36
  drwxr-xr-x 9 root root 4096 Mar  5 16:22 .
  drwxr-xr-x 9 root root 4096 Mar  5 16:24 ..
  drwxr-xr-x 6 root root 4096 Apr 11  2012 1.9.2-p290
  drwxr-xr-x 6 root root 4096 Apr 18  2012 1.9.3-p0
  drwxr-xr-x 6 root root 4096 Apr 18  2012 1.9.3-p125
  drwxr-xr-x 6 root root 4096 Jun  8  2012 1.9.3-p194
  drwxr-xr-x 6 root root 4096 Oct 24 11:40 1.9.3-p286
  drwxr-xr-x 6 root root 4096 Nov 12 15:34 1.9.3-p327
  drwxr-xr-x 6 root root 4096 Nov 13 11:40 2.0.0-preview1

ここはさわれない

mv versions versions.system
mkdir versions
cp -r versions.system/1.9.3-p327 ./versions/

ぬりゃ

# vim /home/sqale/.rbenv/versions/1.9.3-p327/bin/unicorn

# 読み込み先を/usr/local から変えちゃう
#gem 'unicorn', version
#load Gem.bin_path('unicorn', 'unicorn', version)
load '/home/sqale/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/unicorn-4.6.2/bin/unicorn'
# vim /home/sqale/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/unicorn-4.6.2/bin/unicorn
options[:config_file] = '/home/sqale/etc/unicorn/config.rb'

Unicorn::Launcher.daemonize!(options) if rackup_opts[:daemonize]
Unicorn::HttpServer.new(app, options).start.join

無理矢理上書きする

ここから何ができそうかなというのはよくわからない