個人で開発しているウェブアプリケーションのエラー管理には Airbrake 互換の errbit を使っていたのですが、 Sentry が良いらしい、という話を聞いて、 Sentry について調べていたら、 Sentry には Self-Hosted 版があるらしいということで、さくらのVPSの CentOS 7 に Sentry の Self-Hosted 版をインストールしてみました。
Self-Hosted 版のインストール方法は Sentry のオフィシャルドキュメントが詳しいがあるので、その通りに進めていけば特に問題はないのですが、 Self-Hosted 版 Sentry は Python 2.7 + Django + PostgreSQL + Redis という構成で、特に Python と PostgreSQL はほとんど触ったことがなかっため、インストールを進める中で Ruby や MySQL との文化の違いなどで戸惑うことがわりとたくさんあったことと、 Self-Hosted 版の Sentry のインストール方法について日本語で書かれたブログ記事はなさそうだったので、これから Self-Hosted 版の Sentry をインストールしてみたい人の役に立つのではと思い、インストールの手順をまとめてみます。
各種バージョン
- OS: CentOS 7.7
- Python: 2.7.16
- PostgreSQL: 12.0
- Redis: 5.0.6
- Sentry: 9.1.2
Python は3系ではなく 2.7 とのことです。2系のサポートっていつまでだっけ、と思いながらインストール作業をしていました。(改めて調べたら「2020年1月1日」までとのことなので、この記事の公開時点であと2ヶ月無いですね…。 Self-Hosted 版の Sentry の今後が気になります…。)
PostgreSQL は 9.6 が推奨らしいのですが、まぁバージョンが上な分には問題ないだろうと思って、記事執筆時点の最新の PostgreSQL 12.0 を使用しました。(結果、 PostgreSQL 12.0 で問題なく動きました。)
Redis は 3.2 が推奨らしいのですが、まぁバージョンが上な分には問題ないだろうと思って、記事執筆時点の最新の Redis 5.0.6 を使用しました。(結果、 Redis 5.0.6 で問題なく動きました。)
ちなみに、 docker は使いませんでした。サーバーがさくらのVPSなので、そこで docker を使いたい理由があまりなかったので。
CentOS 7 に sentry
ユーザーを作成
あとで各所で利用するため、 CentOS 7 に sentry
というユーザーを先に作成します。
$ useradd sentry
$ passwd sentry
PostgreSQL 12.0 のインストール
yum でインストールしたいので、 PostgreSQL のオフィシャルのドキュメントにある通り、 PostgreSQL のバージョンを選択して、プラットフォームを選択して、 CPU アーキテクチャを選択して、表示された rpm をインストールします。
$ yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
これで postgresql12
という名前で yum でインストールできるようになります。( postgresql12
がクライアントで postgresql12-server
がサーバーで、 postgresql12-contrib
が拡張機能です。)
$ yum install -y postgresql12 postgresql12-server postgresql12-contrib
postgresql-12-setup initdb
の実行
PostgreSQL は通常、サービスを起動する前に一度だけ、 postgresql-12-setup initdb
を実行する必要があるらしいです。(私は今回、初めて知りました。)
postgresql-12-setup initdb
がはじめ、どこにあるかわからなかったのですが、 /usr/pgsql-12/bin/postgresql-12-setup
にあったので、 それを使って initdb
を実行します。( postgresql-12-setup
の場所は systemctl status postgresql-12
で調べて、なんとなくあたりをつけて見つけました。)
$ /usr/pgsql-12/bin/postgresql-12-setup initdb
postgresql-12 の起動
サービス名がわからなかったので、 systemctl list-unit-files -t service | grep postgres
でサービス名を探して、 postgresql-12
であることを確認しました。サービス名がわかったので、サービスを起動して OS 起動時に自動で立ち上がるようにします。
$ sudo systemctl start postgresql-12
$ sudo systemctl enable postgresql-12
sentry ユーザーと sentry データベースの作成
続いて、Sentry で利用するためのユーザー「 sentry
」とデータベース「 sentry
」を作成します。
PostgreSQL 12.0 をインストールすると posgres
というユーザーが作られていて、このユーザーが PostgreSQL に対するスーパーユーザーになっています。
なので、まずは、 sudo
などで postgres
ユーザーにログインシェルを変更して、
$ sudo su - postgres
postgres
ユーザーで PostgreSQL 12.0 の sentry
ユーザーを作成して、
$ createuser sentry
sentry
データベースを作成します。
$ createdb -E utf-8 -O sentry -T template0 sentry
注意点としては、 Sentry のオフィシャルのドキュメントには createdb -E utf-8 sentry
でデータベースを作る、と書かれているのですが、 template を指定しないと utf-8 で作れなかったため、 template を指定しています。( createdb -E utf-8 sentry
でデータベースを作ろうとすると、「 template に tempate0
を指定しなさい」というエラーメッセージが出た気がしますが、詳しいエラーメッセージは失念しました。)
続いて、下記のコマンドで sentry
ユーザーに対して、 sentry
データベースへの全ての権限を追加します。
$ psql
postgres=# grant all privileges on database sentry to sentry;
GRANT
Sentry に必要な PostgreSQL の拡張機能のインストール
これはあとでわかったことなのですが、 Sentry には citext
という PostgreSQL の拡張機能(エクステンション)が必要でした。
拡張機能のインストールはスーパーユーザーの postgres
で行います。下記のように postgres
ユーザーにログインシェルを変更して、
$ sudo su - postgres
下記のコマンドで PostgreSQL に接続して、
$ psql
利用するデータベースをsentry
に変更して、
postgres=# \c sentry
下記の SQL で citext
をインストールします。
sentry=# create extension citext;
CREATE EXTENSION
Python 2.7.16 のインストール
システムの Python 2.7 はバージョンが 2.7.5 で、2系の最新は 2.7.16 だったので、 pyenv で 2.7.16 をインストールしました。
インストール方法は pyenv の README が詳しいので、 README で説明されているままインストールを進めます。(と言いつつ、一部、アレンジしています…。)
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
$ exec "$SHELL"
$ pyenv -v
pyenv 1.2.13-19-gf3d008f
これで pyenv がインストールできたので、 pyenv で Python 2.7.16 をインストールします。
$ pyenv install 2.7.16
$ pyenv versions
system
* 2.7.16 (set by /home/username/.pyenv/version)
Python 2.7.16 がインストールできました。
Redis 5.0.6 のインストール
Redis の最新を yum でインストールしたくて、調べたところ PHP で有名な remi リポジトリを利用することで Redis v5 が使えるとのことだったので、まずは remi リポジトリをインストールします。
remi リポジトリを利用するために epel リポジトリが必要になるようなので、まずは epel リポジトリをインストールします。
$ yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
次に remi リポジトリをインストールします。
$ yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm
remi リポジトリを有効にして redis をインストールします。
$ yum install -y redis --enablerepo=remi
これで Redis 5.0.6 がインストールできました。
$ redis-server -v
Redis server v=5.0.6 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=c3d7ebb6b1a2844b
Sentry のインストール
まずは適当な場所に sentry
ディレクトリを作成して、
$ mkdir sentry
sentry
ディレクトリに移動して、
$ cd sentry
ここで Python 2.7.16 を利用したいので、 .python-version
を作成して、
$ echo 2.7.16 > .python-version
pyenv rehash
を実行して、
$ pyenv rehash
念のため Python のバージョンを確認します。
$ python --version
Python 2.7.16
Python の作法がよくわかっていないですが、 virtualenv
を使いたいので、 pip
で virtualenv
をインストールして、
$ pip install -U virtualenv
virtualenv
を実行して、
$ virtualenv ./
activate
を実行します。
$ source bin/activate
続いて、 pip
で sentry
をインストールします。
$ bin/pip install -U sentry
これで sentry
コマンドがインストールされました。
$ bin/sentry --version
sentry, version 9.1.2
続いて sentry init
を実行して設定ファイルを生成します。設定ファイルの配置場所は、オフィシャルドキュメントでは /etc/sentry
になっていますが、私は sentry
ディレクトリにまとめたかったので、下記のように実行しました。
$ bin/sentry init config
上記のコマンドで config
ディレクトリ以下に config.yml
と sentry.conf.py
が作成されるので、適宜修正します。
まずは sentry.conf.py
のデータベースへの接続部分を下記のように修正します。
DATABASES = {
'default': {
'ENGINE': 'sentry.db.postgres',
'NAME': 'sentry',
'USER': 'sentry',
'AUTOCOMMIT': True,
'ATOMIC_REQUESTS': False
}
}
次に、 Sentry から送信されるメールを私個人の Gmail を経由して送信するように設定します。
先に Gmail でアプリパスワードの生成を行なって、その内容にあわせて config.yml
の Mail Server の設定を修正します。
mail.backend: 'smtp' # Use dummy if you want to disable email entirely
mail.host: 'smtp.gmail.com'
mail.port: 587
mail.username: 'username@gmail.com'
mail.password: 'Gmail で発行したアプリパスワード'
mail.use-tls: true
# The email address to send on behalf of
mail.from: 'sentry@sentry.example.com'
続いて sentry
ユーザーで sentry upgrade
を実行して、データベースのスキーマ定義を読み込んだり、初期設定を実行したりします。( sentry
ユーザーで実行するのは、 sentry
データベースに接続できるのが OS の sentry
ユーザーのみであるためです。)
$ sudo su sentry -c "SENTRY_CONF=/home/username/sentry/config bin/sentry upgrade"
上記コマンドを実行すると、最後にユーザーを作るか聞かれるので、私は自分のユーザーを作成しました。
Would you like to create a user account now? [Y/n]:
Sentry を systemd に登録して起動する
Sentry を systemd に登録して起動する方法がオフィシャルのドキュメントに記載されているので、ほぼその通りに進めていきます。(ただし、ディレクトリなどは適宜、自分の環境にあわせて修正します。)
まずは sentry-web.service
を下記のように作成します。
$ sudo vi /etc/systemd/system/sentry-web.service
[Unit]
Description=Sentry Main Service
After=network.target
Requires=sentry-worker.service
Requires=sentry-cron.service
[Service]
Type=simple
User=sentry
Group=sentry
WorkingDirectory=/home/username/sentry
Environment=SENTRY_CONF=/home/username/sentry/config
ExecStart=/home/username/sentry/bin/sentry run web
[Install]
WantedBy=multi-user.target
次に sentry-worker.service を下記のように作成します。
$ sudo vi /etc/systemd/system/sentry-worker.service
[Unit]
Description=Sentry Background Worker
After=network.target
[Service]
Type=simple
User=sentry
Group=sentry
WorkingDirectory=/home/username/sentry
Environment=SENTRY_CONF=/home/username/sentry/config
ExecStart=/home/username/sentry/bin/sentry run worker
[Install]
WantedBy=multi-user.target
最後に sentry-cron.service を下記のように作成します。
$ sudo vi /etc/systemd/system/sentry-cron.service
[Unit]
Description=Sentry Beat Service
After=network.target
[Service]
Type=simple
User=sentry
Group=sentry
WorkingDirectory=/home/username/sentry
Environment=SENTRY_CONF=/home/username/sentry/config
ExecStart=/home/username/sentry/bin/sentry run cron
[Install]
WantedBy=multi-user.target
以上、3つのサービスを作成しましたが、 sentry-web
を起動すると sentry-worker
と sentry-cron
も起動するので、通常、コマンドで起動させるのは sentry-web
だけです。(ただ、 sentry-web
を止めても sentry-worker
と sentry-cron
は止まらなかったので、全て止めたい場合は、それぞれを止めるコマンドを実行する必要がありました。)
$ sudo systemctl start sentry-web
上記のコマンドで sentry-web
を起動すると、 service-worker
と service-cron
も起動していることが確認できます。
$ sudo systemctl status sentry-worker
$ sudo systemctl status sentry-cron
最後に sentry-web
を自動起動するように設定しておきます。
$ sudo systemctl enable sentry-web
Nginx の設定
Nginx のインストール方法と、私は SSL 認証書に Let’s Encrypt を使ったのですが、その辺りの話は本題と外れる気がするので、省きます。
Nginx の設定の書き方もオフィシャルのドキュメントに書かれているほぼそのままで、私は下記のように記述しました。( Sentry とあまり関係ない箇所は省いています。)
server {
listen 443 ssl;
server_name sentry.example.com;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded_Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
location / {
proxy_redirect off;
proxy_pass http://localhost:9000;
}
}
また、 SSL の設定として、 config/sentry.conf.py
のコメントアウトされていた行のコメントを削除して有効化しました。
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
ブラウザで Sentry を開く
ブラウザで https://sentry.example.com を開いて、下記のような画面が表示されれば完了です。
Sentry の管理画面の使い方は、使ってみたらなんと無くわかりました。 errbit よりもモダンな感じで、画面遷移などがサクサク動くのが素敵です。
とりあえず、個人で運用している Rails 5 用の Project を作って、そうすると gem のインストール方法と設定の書き方の説明ページが表示されるので、その通りに gem をインストールして、設定を書いて、
Rails アプリで検証用の例外を発生させて、 Sentry にエラーの詳細が送られていることを確認しました。
errbit に比べて情報量が多い気がするけど、ちゃんときれいに整理されてデザインされているので、慣れると使いやすそうです。
以上、 Self-Hosted 版 Sentry を CentOS 7 にインストールした話でした。どなたかのご参考になれば幸いです。
参考サイト
途中、 PostgreSQL をアンインストールした際に下記のサイトが参考になりました。