Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

自宅サーバー用CentOS 7.7にpython環境を構築する

More than 1 year has passed since last update.

2019.11.06に追記しました。

モチベーション

 自宅でのプログラミング環境を整備するためにCentOS7にGitLabとMattermostをインストールした自宅サーバーを運用中(このセットアップは別途記事を準備中。いろいろあってめちゃくちゃ長くなってしまっている...)

 GitLabからのいろいろな通知はMattermostで見れるようになっているが、それ以外にも例えばClamAVでウイルス検知したときや適当なログなどをMattermostのプライベートチャネルに送れたら管理が楽になりそう。Gmailは大量のスパムに埋もれるし。pythonにslackwebというslack等々にメッセージを送れるライブラリがあるようなので、そのインストールが最終目標。

 とはいえ、そもそもpythonについてはサーバー内で特に弄っていなかったため、CentOS 7デフォルトの2.7ではなく3系統が使えるように環境を構築する。もとの環境を汚さないように適当な仮想環境を作るというのでググってみると、pyenvとpipenvによる仮想環境が良さそうだったので当面それを試す。


$と#の補足
コンソールについては$ならばローカルユーザー、#はrootユーザー(sudo su状態)とする。

事前準備

 まずはいつも通りsudo yum updateで一旦環境を最新化する。今回はGitLabが12.4.0から12.4.1に上がっており、少々アップデートに時間がかかった。

pyenvのインストール

 まずはpyenvに必要なパッケージをインストール。

# yum install gcc bzip2 bzip2-devel openssl openssl-devel readline readline-devel sqlite-devel tk-devel git

 次にpyenvをgithubからクローンする。全ユーザーで利用可能なように/usr/local/pyenvに配置。

# git clone git://github.com/pyenv/pyenv.git /usr/local/pyenv
# cd /usr/local/pyenv
# mkdir {versions,shims}  <- ,後にスペースを入れてはいけない

 また、pyenvアップデート用のパッケージもダウンロートしておく。

# cd plugins/
# git clone git://github.com/pyenv/pyenv-update

 pyenv用の環境変数を指定し、パスを通す。

# echo 'export PYENV_ROOT="/usr/local/pyenv"' >> /etc/profile.d/pyenv.sh
# echo 'export PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${PATH}"' >> /etc/profile.d/pyenv.sh

 また、sudo時にPATHを引き継げるように

# visudo

 の上、secure_pathのある行を下記のように編集する。

#Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
Defaults        env_keep += "PATH"
Defaults        env_keep += "PYENV_ROOT"

 これで再ログインか、$ source /etc/profile.d/pyenv.shするとpathが通るのでpyenvが使えるようになる。

$pyenv --version
pyenv 1.2.14-11-gb5f69fe
$pyenv install --list
~ 利用可能なpythonのバージョンがずらずら出る ~

 (pathを通すところまではいいんだけどvisudoの中身の編集がどうしてこうなるのかはきちんと理解できていない。/sbinとかのところ、コメントアウトしていいの...?)

pipenvのインストール

 pip自体が入っていなかったので、そこからインストール。

$curl https://bootstrap.pypa.io/get-pip.py | sudo python
$pip --version
pip 19.3.1 from /usr/lib/python2.7/site-packages/pip (python 2.7)

 次にお待ちかねpipenvのインストール。

$sudo pip install pipenv
$pipenv --version
pipenv, version 2018.11.26

仮想環境自体をフォルダの中に作る #2019.11.06追記

 上記の状態でpipenvは使えていて次節のpipenv --python 3.7.5等でフォルダごと、ないしプロジェクトごとの仮想環境が作れる状態にある。
 ただし、この仮想環境の実体は~/.local/share/virtualenvs/の中に出来上がってしまう。サーバーにログインした際にMattermost上へユーザーの誰がログインしたかをgetpass.getuser()で取得して通知したかったのだが、実体が各ユーザーのホームディレクトリにあるせいで、slackwebを読み込めずエラーを吐いてしまった。pythonのバージョンは他ユーザーでも3.7.5になっていたので、pyenvの環境は読み込んだものの、pipenvの環境が読み込めていなかったようだ。
 回避するには環境変数として$PIPENV_VENV_IN_PROJECTを定義するとよい。これによって仮想環境の実体が各プロジェクトディレクトリの中の.venvディレクトリに格納されるようになる。
 すべてのログインユーザーで各プロジェクトの.venvを使ってほしいので、下記を/etc/bashrcの最後に追記しておく。

/etc/bashrc
# To enable local virtual enviroment for pipenv
export PIPENV_VENV_IN_PROJECT=1

 これで単一のディレクトリの中身だけで使いたいプログラムから環境まで、すべてのユーザーから共通して扱えるようになった。

pyenvとpipenvによるpython仮想環境構築

 当初目標のslackwebの動作確認用のプロジェクトフォルダを作成する。

$mkdir my_program
$mkdir my_program/slackweb
$cd my_program/slackweb

 3.7系最新板のpython 3.7.5を環境に指定する。ただし、3.7系以降の利用にはlibffi-develが必要なようなので、3.7をいれる前にインストールしておく。(これをやらずに後で行ったり来たりしてしまった)

$sudo yum install libffi-devel 
$sudo pyenv install 3.7.5

 これでpyenv経由で3.7.5が入ったので、my_program/slackwebフォルダでこれを利用できるように仮想環境を作る。

$pipenv --python 3.7.5

 この状態でsystemのpythonと、このフォルダにおけるpipenvのpythonのバージョンが違うことを確認する。

$python --version
Python 2.7.5
$pipenv run python --version
Python 3.7.5

 pipenv runを頭につけておくとその環境下でコマンドを利用したことになる。ちょっとした確認ではそれでいいが、仮想環境下に入りその後のコマンドはすべて仮想環境でのpythonで実施したい場合その後のコマンドはすべて仮想環境でのpythonで実施したい場合、pipenv shellで環境に入る。出るときはexit
 pyenvを先にやらずにいきなりpipenvからやっても、pyenvと連携してpythonのインストールからやってくれるようだが、その場合sudoでやらないといけない。そうすると作った仮想環境がroot配下になってしまいそうなので(?)、今回は分離して実行。
pyenvのインストールをローカルユーザーのみにして自分だけにパスを通せばsudoがいらなくなる(のか?)

 最後にslackwebをインストール。

$pipenv install slackweb

 通常のシェルでpip listとするとsystemのpipでインストールされたあれやこれやが表示されるが、仮想環境下だと

[name@localhost slackweb]$ pipenv shell
(slackweb) [name@localhost slackweb]$ pip list
Package    Version
---------- -------
pip        19.3.1
setuptools 41.6.0
slackweb   1.0.5
wheel      0.33.6

このように自分の作った仮想環境の中身が確認できる。
 slackwebが動くかどうかのテストは次の通り。

(slackweb) [name@localhost slackweb]$python
Python 3.7.5 (default, Nov  3 2019, 00:13:05)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import slackweb
>>> slack = slackweb.Slack(url="自分のMattermostの内向きウェブフックアドレス")
>>> slack.notify(text="This is a test from inside of the server.")

MattermostのTown SquareにThis is a test from inside of the server.と表示されたので目標達成。これで今後はいろいろな通知がMattermostに出せて便利。いろいろはかどりそう。

Mattermostへログイン通知をさせる #2019.11.06追記

 実際にサーバーログイン時にMattermostへ通知するプログラムを用意した。

login_notification.py
import slackweb
import getpass

slack = slackweb.Slack(url="自分のMattermostの内向きウェブフックアドレス")
attachments = []
attachment = {"title": "Login notification",
              "pretext": "This is a notification from _サーバーのFQDN_",
              "text": "**" + getpass.getuser() + "** logged in.",
              "mrkdwn_in": ["text", "pretext"]}
attachments.append(attachment)
slack.notify(channel="#通知先チャネル名",
             username="CentOS 7",
             attachments=attachments)

 ちなみにgetpassモジュールはpythonのデフォルトライブラリであって、pipenvで入れようとする必要などない(というか出来なくてエラーに悩むだけ。時間を無駄にしてしまった...)。もしうっかりインストールしてしまったらPipfileに変な記録が残ってしまうので、pipenv uninstall getpass, pipenv cleanで余計な情報を消しておく。

 あとはこれを実行すればログイン通知ができる。pipenv run python login_notification.pyをするだけだが、ログイン時に一度だけ自動で通知されてほしい。そこでこれもまた全ユーザーでそうなるように、/etc/bashrcの最後に追記して対処する。

/etc/bashrc
# Notify the login to mattermost
cd /home/username/my_program/slackweb/    <- usernameは上の環境やプログラムを作ったユーザー
pipenv run python login_notification.py
cd ~     <- 後で何をするかわからないので、ログインユーザーのホームに戻っておく

 これでsshでログインしたり、sudo suするたびに各ユーザーやrootなどでのログインがされたという通知がMattermostに送られるようになった。Mattermostはスマホへの通知の連携なども簡単にできるので、これで自分の知らない間に怪しい人物が乗っ取りを行ったとしても即座に気づくことが出来る。
あくまで心の安寧のための保険なので、アクセスのための秘密鍵が漏洩しないようにすることがもっと大事だけれど、人間安心できるというのはとても大事だと思う。
(そういう意味ではこの記事をアップする際にウェブフックとかユーザー名とかうっかり晒してないか心配で全然安心できてない)

参考サイト

CentOSにPyenvをインストールしてPython3の開発環境を構築する

[Python] pyenv と pipenv による python 仮想環境を構築する(CentOS 7 ほぼ初期状態から )

Python 開発に Pipenv を使うようにしてみた

Pipenv: 人間のためのPython開発ワークフロー(pipenv公式)

Slackにincoming webhook経由でpythonからメッセージをPOSTする

s_ponta
個人的な備忘録として記録をつけてます。 DIYとか趣味プログラミング的なものONLY。 仕事のことはOpenにするとややこしいので書かない方針。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away