CentOS7にJupyter NotebookをインストールしてローカルPCから接続
はじめに
最近データ加工などのためにローカルPCでJupyter Notebookを使っています。
でも、時間のかかる処理が必要なこともあるため、そういうときはサーバ側で実行したいです。
そこで、CentOS7にJupyter Notebookをインストールして、ローカルPCから接続するまでの方法を調べてまとめました。
環境
- CentOS 7.2
- anaconda3-4.3.1
さくらのvpsに新規でCentOS7を立ち上げた状態からJupyter Notebookをインストールして、ローカルPCから接続する想定です。
セキュリティの設定
まずはOS再インストール後すぐに、さくらVPSのCentOS7のセキュリティ設定を見て対応していきました。
(参考サイト:チュートリアル:CentOS 7(さくらのVPS)サーバ作成直後に設定しておくべき初期セキュリティ設定 – さくらのVPSニュース)
上記サイトが分かりやすかったのでそのまま設定をします。
ここで作成した秘密鍵とパスフレーズは後のサーバ接続のために利用します。
公開鍵認証でのローカルからのSSH接続のコマンドをよく忘れるのでメモします。 上記設定の後だと一般ユーザで公開鍵認証でしかログインできなくなります。
ssh -i ~/.ssh/id_rsa ユーザ名@IPアドレス
Jupyter Notebookのインストール
色々インストール方法はありますが、本記事ではpyenvをインストールしてからAnacondaをインストールします。 Anacondaを入れるとpython本体に加えてデータ分析等のよく使われるライブラリも同時にインストールできます。 その中にjupyter notebookも含まれます。
自分が過去に書いたPythonインストール記事を参考にします。
以下を実行してインストールからjupyter notebook起動までを行います。
(参考サイト:CentOSにPython環境を作ってみたまとめ - 薮蛇なエンジニアの開発備忘録)
yum update -y yum install -y gcc gcc-c++ make git openssl-devel bzip2-devel zlib-devel readline-devel sqlite-devel bzip2 sqlite git cd /usr/local/src/ git clone https://github.com/yyuu/pyenv.git echo 'export PYENV_ROOT="/usr/local/src/pyenv"' >> /etc/profile.d/pyenv.sh echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> /etc/profile.d/pyenv.sh echo 'eval "$(pyenv init -)"' >> /etc/profile.d/pyenv.sh exec $SHELL -l pyenv --version pyenv install --list pyenv install anaconda3-4.3.1 pyenv global anaconda3-4.3.1 pyenv rehash python --version cd ~ mkdir workspace cd workspace jupyter notebook
これでjupyter notebookを起動できます!
(でも、まだローカルPCからはアクセスできません)
notebook起動後、以下のようなメッセージが出力されるので token=以下の文字列をあとで利用します。
[NotebookApp] Copy/paste this URL into your browser when you connect for the first time, to login with a token: http://localhost:8888/?token=xxxxxxxxx(毎回異なるトークンが入る)
注意
自分が過去にpyenvを使ったので今回も利用しましたが、
改めてPython環境周りを調べると構成を再検討した方が良さそうでした。
でも、今回は取り急ぎjupyter notebookをインストールする一例としてこのまま進めます。
SSHポートフォワーディングについて
サーバにインストールしたnotebookにアクセスする方法を調べたところ次の2つが見つかりました。 個人的な利用を想定しているため(2)を採用しました。
(1) notebookを公開してパスワードをつける
(2) SSHポートフォワーディングでサーバに接続する
ポートフォワーディングについては次のように理解しています。
■SSHコマンドに-L オプションをつけるとポートフォワーディングできる
例:ssh -L 7777:localhost:8888 ユーザ名@IPアドレス
■ローカル指定ポートにアクセスで、サーバ上から指定場所にアクセスできる
例:上記のコマンドのあとローカルPCでlocalhost:7777にアクセスするとサーバ側から繋いだlocalhst:8888にアクセスできる(つまり、jupyternotebookがサーバ内部でしか見れなかったとしてもポートフォワーディングすればローカルPCから閲覧可能)
(ポートフォワーディングの参考サイト:サーバー上の Jupyter Notebook を SSH Port Forwarding を通して使う | kuune.org)
ローカルPCからの接続
ssh -L 7777:localhost:8888 ユーザ名@IPアドレス -i ~/.ssh/id_rsa
jupyterを起動したのとは別のターミナルを立ち上げて、
公開鍵認証でポートフォワーディングする上記のコマンドを実行します。
その後ブラウザでlocalhost:7777に接続すると、次のような画面が出てきます。
「Passsword or token:」の部分に、jupyter起動時のtoken=以下の文字列をコピペして「Log in」ボタンを押します。
これでローカルPCからサーバのjupyter notebookにアクセスできます!
使いやすくする工夫
■jupyter notebookがターミナルを閉じると止まる
これまでの方法だと、jupyter notebookを起動したターミナルを閉じるとjupyterも停止してしまいます。
ターミナルを閉じた後も停止させないようにするためにはnohupをつけると良いようです。
(参考サイト1:Jupyter Notebook を永続的に起動させる方法 - 約束の地)
(参考サイト2:プロセス管理: nohup, disown, kill - Heavy Watal)
nohup jupyter notebook >~/jupyter_out.txt 2>~/jupyter_err.txt &
上記のコマンドを打つとターミナルを閉じた後も、ポートフォワーディングさえできていればローカルPCからjupyterに接続できました。
バックグラウンド実行中でtokenを確認したくなったときはjupyter notebook listで見れます。
ターミナルをしばらく操作しないでいるとタイムアウトされるため、頻繁に接続しなおすことになり面倒です。
なるべくタイムアウトを引き伸ばす方法を調べました。
(参考サイト:ターミナルのSSH接続が切れすぎるので設定いじった話 - helen's blog)
以下のようにsshd_configを修正して再起動しました。
sudo vim /etc/ssh/sshd_config
sudo systemctl restart sshd
変更前
# ClientAliveInterval # ClientAliveCountMax
変更後
ClientAliveInterval 60 ClientAliveCountMax 12
これでだいぶ切断頻度が下がりました!
まとめ
CentOS7のサーバにJupyter Notebookをインストールし、ローカルPCから接続する方法をまとめました。
これで時間のかかる処理を実行したときにファンの音などPCを気にせずにすみそうです。また、iPadのSafariからでもサーバで起動したnotebookを表示できたので、くつろぎながら進捗確認をしたり色々捗りそうです。
PythonでPostgreSQLに接続してみた
概要
前回の記事ではPostgreSQLのインストールを行いました。今回はPythonからPostgreSQLへの接続を行う方法をまとめます。
(前回のPostgreSQLのインストール記事:PostgreSQLをyumでインストール(yumとrpmの復習込み) - 薮蛇なエンジニアの開発備忘録)
PythonからDB接続するためにはドライバというモジュールをインストールする必要があるようです。
psycopg2というドライバが2016/1時点で一番DLされているようなので、そちらを利用しました。
(参考サイト:PythonからPostgreSQLに接続する方法 | アシスト)
psycopg2のインストール
シンプルにpipでインストールしたところエラーが出てしまいました。
pip install psycopg2
エラー内容から一部抜粋
Error: pg_config executable not found. Please add the directory containing pg_config to the PATH or specify the full executable path with the option: python setup.py build_ext --pg-config /path/to/pg_config build ... or with the pg_config option in 'setup.cfg'.
エラーをgoogleで検索したところ既に解決している方がいたので、その方法を使わせて頂きました。
(参考サイト:Python / PostgreSQL on Heroku でpsycopg2がない & pg_configがないと怒られる時 - 木木木)
pg_configへのPATHを追加してください的な内容のエラーなので、pg_configの場所を調べてPATHに追加してやれば良いようです。
以下は解決方法の引用です。
locate pg_config
これで私の場合は/usr/pgsql-9.4/bin/pg_configが出てきたので次のようにしました。
2016.05.20追記:別の環境で構築したところ、locateコマンドを叩いても何も表示されませんでした。updatedbというコマンドを叩くとlocate用ファイルが更新されてパスが表示されるようになりました。
export PATH="/usr/pgsql-9.4/bin:$PATH"
再度インストール
pip install psycopg2 python >>> import psycopg2 >>> >>> exit()
無事インストールできて、実際にimportして確認してもエラーは出ませんでした。
2016.05.20追記:何故かbottle環境からpsycopg2を利用しようとするとインポートエラーになりました。yum -y install psycopg2を実行したところ直りました。yumとpipの関係が分かっていないので今後調べます。
今回の私の原因とは違うので余談ですが、postgresql-develをインストールしていない場合でも Error: pg_config executable not found. のエラーが起きるようです。
(参考サイト:(Djangoメモ)データベースにPostgreSQLを設定 - Qiita)
pythonからPostgreSQLに接続
DBユーザの作成、DBの作成は済ませているものとします。
以下のサイトを参考にしてまずはDB接続を行いました。
(参考サイト:PythonからPostgreSQLに接続する方法 | アシスト)
【】で括った部分は既に作成済みのDB情報に合わせるものとします。
python >>> import psycopg2 >>> connection = psycopg2.connect("host=【IPアドレス】 port=5432 dbname=【DB名】 user=【ユーザ名】 password=【パスワード】")
これで繋がると思ったらエラーが出てしまいました。
エラー内容から一部抜粋
psycopg2.OperationalError: could not connect to server: Connection refused
接続が拒否されているようなので、外部から接続できるように設定します。以下のサイトを参考に試みました。
(参考サイト1:http://rina.jpn.ph/~rance/linux/postgresql/connect.html)
(参考サイト2:PostgreSQLのポート番号を変更する - (=゜ω゜)ノぃょぅ にっき)
まずは受け入れポート等の設定変更
locate postgresql.conf vim /var/lib/pgsql/9.4/data/postgresql.conf
postgresql.confの中身からlisten_addressとportのコメントを外して書き換え
listen_addresses = 'localhost, 【IPアドレス】' port = 5432
接続できるクライアントの指定
locate pg_hba.conf vim /var/lib/pgsql/9.4/data/pg_hba.conf
pg_hba.confに以下内容を追加
host all all 【IPアドレス】/32 trust
service postgresql-9.4 restart
設定を変更してpostgresqlを再起動した後、再びpsycopg2.connect(引数は省略)を実行したところ、正常に接続することができました。
注意:pg_hba.confで接続できるクライアントのIPアドレスに、自身のIPアドレスを指定して追加しただけなのでセキュリティ的に大丈夫と思いますが、この設定内容を利用する方がいましたら各自で再度問題ないかご確認ください。
INSERTとSELECTの実行
データベースに接続できたので、INSERTとSELECTを実行してみます。
(参考サイト:psycopg2によるPython2.7からのAmazon Redshiftアクセスサンプル | Developers.IO)
python >>> import psycopg2 >>> conn = psycopg2.connect( ... host="【IPアドレス】", ... database="【DB名】", ... port="5432", ... user="【ユーザ名】", ... password="【パスワード】" ... ) >>> cursor = conn.cursor() >>> cursor.execute("INSERT INTO table_name (column1) VALUES ('hoge')") >>> cursor.execute("INSERT INTO table_name (column1) VALUES ('fuga')") >>> cursor.execute("SELECT * FROM table_name") >>> results = cursor.fetchall() >>> for row in results: ... print(row[0]) ... hoge fuga >>> conn.commit() >>> cursor.close() >>> conn.close()
【】で括った項目とtable名とカラム名は事前に作成しておいた名前を入力するものとします。
insertしたhogeとfugaをselectの結果として表示することができました。
ここでは全件取得でcursor.fetchall()を用いましたが、1レコードだけ取り出すときはcursor.fetchone()を利用するようです。
プレースホルダの利用
以下のサイトを見ながらプレースホルダを使用してみました。
(参考サイト:PostgreSQLをPythonからpsycopg2を使っていじる — そこはかとなく書くよん。)
一つ前に書いたコード中のINSERT文を次のように置き換えできました。
cursor.execute("INSERT INTO table_name (column1) VALUES (%s)", ["hoge"])
値の渡し方に癖があるらしく、("hoge")にすると受け付けないらしいです。
あとINT型でも%sを使うようです。
明示的なCOMMIT/ROLLBACKの必要性
以下のサイトによりますと、参照の処理だけでもトランザクション開始されるようなので、明示的にCOMMIT/ROLLBACKする必要性があるとのことです。
(参考サイト:PythonからPostgreSQLに接続する方法 | アシスト)
自動COMMITさせるためには次のように属性を変更すると可能なようです。
>>> connection.autocommit = True
まとめ
PythonでPostgreSQLに接続する方法について調べて、基本的なDB操作ができるようになりました。
PostgreSQLのインストールさえできていればPythonから簡単に呼び出せるかと思っていましたが、意外と設定に苦戦してしまいました。
もっとスマートな環境構築方法やPostgreSQLの設定等についてはおいおい詳細を勉強していきたいです。
PostgreSQLをyumでインストール(yumとrpmの復習込み)
概要
PostgreSQLをCentOSにインストールしようと思って調べたところ、yumを使った方法が何種類か見つかりました。 どれも根本は同じ事をしているように見えますが、コマンドが微妙に違っています。 yumとrpmについて自分の理解度が低かったせいで混乱しかけたので、改めてyumとrpmの関係を復習しつつPostgreSQLのインストールを実践してみようと思います。
続きを読むApacheでPythonを動かしてみた(bottle利用)
概要
前の記事ではPythonプログラムをサーバに公開するためにApacheを利用しました。
(前の記事→ApacheでPythonを動かしてみた(mod_wsgiをソースからインストール) - 薮蛇なエンジニアの開発備忘録)
しかし少し調べてみると、Pythonは自前でWEBサーバ機能を持っているらしくミドルウェア無しでもサーバとして公開できるようでした。またbottleというシンプルなフレームワークを使えばURLルーティングなども分かりやすくできるようです。…そんな簡単にできたなんて!
とはいえサーバ用ミドルウェアを使っておいた方が安定すると思うので、Apacheでbottleフレームワークを利用する方法について調べてみました。
これで、自分がやりたかった「Pythonでプログラム書いてサーバに公開する」ためのインフラがほぼできたと思います。
続きを読む