Python で作成したツールがあり、通常はデーモンとして実行する必要があります。このツールを配布用にパッケージ化するためのベスト プラクティスは何ですか?特に、設定ファイルとデーモンの実行可能ファイル/スクリプトをどのように処理する必要がありますか?
関連して、特定のプラットフォーム (つまり、Linux のinitスクリプト、Windows のサービス、OS Xのlaunchd ) に応じて起動時に実行するデーモンをセットアップするための一般的なツールはありますか?
Python で作成したツールがあり、通常はデーモンとして実行する必要があります。このツールを配布用にパッケージ化するためのベスト プラクティスは何ですか?特に、設定ファイルとデーモンの実行可能ファイル/スクリプトをどのように処理する必要がありますか?
関連して、特定のプラットフォーム (つまり、Linux のinitスクリプト、Windows のサービス、OS Xのlaunchd ) に応じて起動時に実行するデーモンをセットアップするための一般的なツールはありますか?
init.d スクリプトを支援するために私が見つけた最良のツールは、「start-stop-daemon」です。任意のアプリケーションを実行し、run/pid ファイルを監視し、必要に応じてそれらを作成し、デーモンを停止する方法を提供し、プロセスのユーザー/グループ ID を設定し、プロセスをバックグラウンド化することもできます。
たとえば、これは wsgi サーバーを開始/停止できるスクリプトです。
#! /bin/bash
case "$1" in
start)
echo "Starting server"
# Activate the virtual environment
. /home/ali/wer-gcms/g-env/bin/activate
# Run start-stop-daemon, the $DAEMON variable contains the path to the
# application to run
start-stop-daemon --start --pidfile $WSGI_PIDFILE \
--user www-data --group www-data \
--chuid www-data \
--exec "$DAEMON"
;;
stop)
echo "Stopping WSGI Application"
# Start-stop daemon can also stop the application by sending sig 15
# (configurable) to the process id contained in the run/pid file
start-stop-daemon --stop --pidfile $WSGI_PIDFILE --verbose
;;
*)
# Refuse to do other stuff
echo "Usage: /etc/init.d/wsgi-application.sh {start|stop}"
exit 1
;;
esac
exit 0
また、virtualenv での使用方法の例も参照できます。これは常にお勧めします。
あなたの質問の一部に答えるために、WindowsやMac OS Xはもちろん、Linuxシステム間でもデーモンのセットアップを移植可能にするツールはありません。
現在、ほとんどのLinuxディストリビューションはstart-stop-daemon
initスクリプト内で使用しているようですが、ファイルシステムのレイアウトにはわずかな違いがあり、パッケージには大きな違いがあります。autotools / configureを使用するか、プロジェクトがすべてPythonの場合はdistutils / easy_installを使用すると、さまざまなLinux/BSDディストリビューション用のパッケージを簡単に構築できるようになります。
Windowsはまったく別のゲームであり、MarkHammondのwin32拡張機能とTimGoldenのWMI拡張機能が必要になります。
「上記のどれでもない」が関係していることを除いて、Launchedはわかりません。
Pythonスクリプトをデーモン化するためのヒントについては、Twisted内など、現実の世界で実際にそれを実行しているPythonアプリを探します。
純粋なPython(bashスクリプトなし)でデーモンを作成するためのスニペットがインターネット上に多数あります。
http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ きれいに見えます...
自分で書きたい場合
は、bashデーモン機能と同じ原理です。
基本的に:
開始時:
停車中:
しかし、これを行う広く使用されているパッケージはわかりません。
ベンフィニーのデーモンモジュールを確認してください。彼はPython3.Xを対象としたPEPの作成を開始しました。
http://www.python.org/dev/peps/pep-3143/
しかし、実装はすでにここで利用可能です:
あなたが求めていることに対する特効薬ではありませんが、Supervisordをチェックしてください。プロセス管理のすべての楽しいビットを処理します。大規模な本番環境で頻繁に使用します。また、Pythonで書かれています!
どこでダウンロードしたか覚えていませんが、これは私が見つけた中で最高のデーモン化スクリプトです。(Mac と Linux で) 美しく動作します (daemonize.py として保存します)。
import sys, os
def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
# Perform first fork.
try:
pid = os.fork( )
if pid > 0:
sys.exit(0) # Exit first parent.
except OSError, e:
sys.stderr.write("fork #1 failed: (%d) %sn" % (e.errno, e.strerror))
sys.exit(1)
# Decouple from parent environment.
os.chdir("/")
os.umask(0)
os.setsid( )
# Perform second fork.
try:
pid = os.fork( )
if pid > 0:
sys.exit(0) # Exit second parent.
except OSError, e:
sys.stderr.write("fork #2 failed: (%d) %sn" % (e.errno, e.strerror))
sys.exit(1)
# The process is now daemonized, redirect standard file descriptors.
for f in sys.stdout, sys.stderr: f.flush( )
si = file(stdin, 'r')
so = file(stdout, 'a+')
se = file(stderr, 'a+', 0)
os.dup2(si.fileno( ), sys.stdin.fileno( ))
os.dup2(so.fileno( ), sys.stdout.fileno( ))
os.dup2(se.fileno( ), sys.stderr.fileno( ))
スクリプトでは、次のようにします。
from daemonize import daemonize
daemonize()
また、stdio、err などをリダイレクトする場所を指定することもできます...
このブログエントリは、Pythonプログラムをデーモンとして実行する一般的な方法が2つあることを私に明らかにしました(既存の回答からそれほど明確に理解していませんでした):
Pythonでサーバーのようなデーモンアプリケーションを作成するには、2つのアプローチがあります。
- 1つ目は、Pythonコード自体でデーモンの起動と停止のすべてのタスクを処理することです。これを行う最も簡単な方法は、
python-daemon
最終的にPythonディストリビューションに組み込まれる可能性のあるパッケージを使用することです。
Poeljaponの答えは、この最初のアプローチの例ですが、パッケージは使用していませんがpython-daemon
、カスタムでありながら非常にクリーンなPythonスクリプトにリンクしています。
- もう1つのアプローチは、オペレーティングシステムが提供するツールを使用することです。Debainの場合、これは
start-stop-daemon
プログラムを利用するinitスクリプトを書くことを意味します。
Ali Afsharの答えは、を使用した2番目のアプローチのシェルスクリプトの例ですstart-stop-daemon
。
私が引用したブログエントリには、シェルスクリプトの例と、システムの起動時にデーモンを起動したり、何らかの理由でデーモンが停止したときにデーモンを自動的に再起動したりするなどの詳細が含まれています。
Linux システムでは、システムのパッケージ マネージャー (Gentoo の場合は Portage、Ubuntu/Debian の場合は Aptitude、Fedora の場合は yum など) が通常、適切な場所に init スクリプトを配置するなど、プログラムのインストールを処理します。プログラムを Linux 用に配布する場合は、さまざまなディストリビューションのパッケージ マネージャーに適した形式にまとめることを検討することをお勧めします。
このアドバイスは、パッケージ マネージャーを持たないシステム (Windows と Mac だと思います) には明らかに関係ありません。
間違っている場合は修正してください。ただし、問題はデーモンをデプロイする方法だと思います。アプリを pip 経由でインストールするように設定し、entry_point を にしcli(daemon())
ます。次に、単に実行するinitスクリプトを作成します$app_name &
「通常、デーモンとして実行する必要がありますか?」
表面的にはあまり意味がありません。「一般的に」は賢明ではありません。デーモンかそうでないかのどちらかです。質問を更新することをお勧めします。
デーモンの例については、Apache の httpd や任意のデータベース サーバー (これらはデーモンです)、または SMTPD メール デーモンなどのデーモンを参照してください。
または、おそらく、FTP デーモン、SSH デーモン、Telnet デーモンなど、より単純なものを読んでください。
Linux の世界では、アプリケーションのインストール ディレクトリ、いくつかの作業ディレクトリ、および構成ファイル ディレクトリがあります。
アプリケーションに使用/opt/ourapp
します (Python ですが、Python の にはインストールしませんlib/site-packages
) 。
/var/ourapp
作業ファイルと構成ファイルに使用します 。
構成ファイルに使用することもでき/etc/ourapp
ますが、一貫性がありますが、そうではありません。
init.d
スタートアップ用のスクリプトはまだ使用していません。しかし、それが最後のピース、自動スタートアップです。今のところ、システム管理者にデーモンを開始させます。
これは、部分的にhttp://www.pathname.com/fhs/およびhttp://tldp.org/LDP/Linux-Filesystem-Hierarchy/html/Linux-Filesystem-Hierarchy.htmlに基づいています。