katekichiのゆるブログ

普段の作業メモや日常の出来事とか

Amazon Linuxでgunicorn+supervisorをした際のメモ

今更感がありますが、ずっとアプリケーションサーバーは、主にuwsgiを使用していて gunicornを触ってこなかったので、良い機会なので使ってみたのと、supervisourを使って デーモン化してみたのでメモです。

環境

  • Amazon Linux
  • Python 3.5.2 (DjangoWSGIアプリケーションで使用済) (supervisourは、現状3系未対応のため Amazon LinuxのデフォでインストールされているPython2.7を使用します)

supervisorのインストール

$ sudo /usr/bin/pip install supervisor
Traceback (most recent call last):
  File "/usr/bin/pip", line 5, in <module>
    from pkg_resources import load_entry_point
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 3020, in <module>
    working_set = WorkingSet._build_master()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 616, in _build_master
    return cls._build_from_requirements(__requires__)
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 629, in _build_from_requirements
    dists = ws.resolve(reqs, Environment())
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 807, in resolve
    raise DistributionNotFound(req)
pkg_resources.DistributionNotFound: pip==6.1.1

pipが古いようなのでrootになって更新

$ sudo su -
# /usr/bin/easy_install --upgrade pip
$ exit

再度トライ

$ sudo /usr/bin/pip install supervisor
Requirement already satisfied: supervisor in /usr/local/lib/python2.7/site-packages
Requirement already satisfied: meld3>=0.6.5 in /usr/local/lib/python2.7/site-packages (from supervisor)

pipの更新時に既にインストールされたらしい・・

$ /usr/bin/pip freeze
・・略
supervisor==3.3.3

supervisorのconfファイル

$ sudo su - root -c "echo_supervisord_conf > /etc/supervisord.conf"
$ sudo mkdir /etc/supervisord.d

ログ設定の変更

ログのパスを変更

$ sudo vi /etc/supervisord.conf

[supervisord]
;logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile=/var/log/supervisor/supervisord.log ; main log file; default $CWD/supervisord.log

ログローテーションの設定

$ cd /etc/supervisord.d
$ sudo sh -c "echo '/var/log/supervisor/*.log {
       missingok
       weekly
       notifempty
       nocompress
}' > /etc/logrotate.d/supervisor"

pid, includeの設定

$ sudo vi /etc/supervisord.conf


[supervisord]

# pidファイル(/var/run配下にpidを生成するように変更)
pidfile=/var/run/supervisord.pid

# includeセクションのコメントを外す + 拡張子を変更
[include]
files = /etc/supervisord.d/*.conf

supervisordをサービス登録

Amazon Linuxは、systemdが無いためinitスクリプトを作成する必要があります。 素で書くのは厳しいため、以下を使います。

initscripts/redhat-init-equeffelec at master · Supervisor/initscripts · GitHub

$ sudo curl -o /etc/rc.d/init.d/supervisord https://raw.githubusercontent.com/Supervisor/initscripts/master/redhat-init-equeffelec
$ sudo chmod 755 /etc/rc.d/init.d/supervisord
$ sudo chkconfig --add supervisord

起動確認

$ sudo service supervisor start
Starting supervisord: /bin/bash: /usr/bin/supervisord: No such file or directory
                                                           [FAILED]

となりエラーとなったので、シンボリックリンクを貼ります。

# シンボリックリンクを貼る
$  sudo ln -s /usr/local/bin/supervisord /usr/bin/
$  sudo ln -s /usr/local/bin/supervisorctl /usr/bin/

# 再度、起動
$ sudo service supervisord start
Starting supervisord: 

# プロセス確認
root      3765     1  0 22:09 ?        00:00:00 /usr/bin/python2.7 /usr/bin/supervisord -c /etc/supervisord.conf
ec2-user  3771  3375  0 22:09 pts/0    00:00:00 grep --color=auto supervisord

gunicorn用のconfig設定

今回は、/etc/supervisord.d/django_app.confを作成

[program:django_app]
directory=[アプリケーションパス:Djangoのproject_rootを指定]
command=/home/ec2-user/.pyenv/versions/3.5.2/bin/python3.5 /home/ec2-user/.pyenv/versions/3.5.2/bin/gunicorn jsl_attendance.wsgi --bind=0.0.0.0:8001
numprocs=1
autostart=true
autorestart=true
user=ec2-user
redirect_stderr=true
environment=DJANGO_SETTINGS_MODULE="xxxx.settings.production" # settings.pyを分けているのでproduction用に設定

configの読み込みと、gunicornの起動

configを読み込みます。

$ sudo service supervisord reload

起動は、supervisorctlで実行します。

$ sudo supervisorctl start django_app
django_app: started

まとめ

pipのバージョンが古かったりで、少々ハマってしまいましたがなんとか出来ました。 本来は、 グローバルのPython(2.x)に直接pipインストールはせずに仮想環境を作成した方が良かったです。 とは言うものの、2系と3系で仮想環境を作るのが手間なので、早くsupervisorが3系対応してくれればなと 思いました。

参考サイト/ブログ等

http://supervisord.org/installing.html

Supervisorで簡単にデーモン化 - Qiita

EC2にNginx + Gunicorn + SupervisorでDjangoアプリケーションをデプロイする - Qiita