One-off dyno
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2023年05月24日(水)
Table of Contents
Procfile で宣言され、Dyno Manager によって heroku ps:scale
で管理される一連の dyno は、Dyno formation と呼ばれます。 これらの dyno は、アプリの通常の処理 (Web リクエストの処理やバックグラウンドジョブの処理など) を実行するために使用されます。
タスクの One off 管理またはメンテナンスタスクを行う場合、または Heroku Scheduler を使用して特定のタスクを定期的に行う場合は、One-off dyno をスピンアップできます。
One-off dyno
アプリケーションを Heroku にプッシュすると、slug コンパイラによって、アプリケーションが含まれる slug が生成されます。アプリケーションには、Web サーバー、コンソールアプリケーション、スクリプトなど、データベースを初期化するためのコンポーネントが多数含まれる可能性があります。Web dyno は Procfile で定義され、プラットフォームで管理されますが、コンソールとスクリプトは必要な場合にのみ実行されます。それらが One-off dyno です。
One-off dyno の実行にかかる時間はすべてその使用とみなされ、他の dyno と同様に請求対象となります。
Formation Dyno 対 One-off dyno
One-off dyno は、アプリケーションの Web、Worker、およびその他の Formation dyno と同様、他の dyno と並列して実行されます。One-off dyno には、dyno の分離によるメリットがすべて備わっています。
dyno にはそれぞれ他の dyno とは共有されない、接続が切断されると破棄される一時的なファイルシステムがあります。 このファイルシステムには slug のアーカイブが入力されるため、One-off dyno はアプリケーション内でデプロイされたあらゆるものを最大限に活用できます。
One-off dyno (heroku run
で実行される) と Formation dyno (heroku ps:scale
で実行される) の間にはいくつかの違いがあります。
- One-off dyno は、ターミナルに接続され、
STDIN
およびSTDOUT
の文字単位の TCP 接続を使用してして実行されます。 これにより、コンソールなどの対話型プロセスを使用できます。STDOUT
がターミナルに出力されるため、アプリのログでは dyno の起動とシャットダウンのみが記録されます。 - One-off dyno は、Ctrl+C を押すか、ローカルターミナルで接続を切断するとすぐに終了します。 プロセスが自然に終了しても、ユーザーが手動で接続を切断しても、One-off dyno が自動で再起動することはありません。
- One-off dyno は、スキーマ
<process-type>.N
ではなくスキーマrun.N
で命名されます。 - ルーターは、
web.N
という名前の dyno にのみトラフィックをルーティングするため、One-off dyno が HTTP トラフィックを受信することはありません。 - One-off dyno は、新しいアプリのリリースの後に再起動されません。
これらの違いのほかに、Dyno Manager では One-off dyno と Formation dyno は区別されません。
One-off dyno の例
One-off dyno は heroku run
を使用して作成されます。 One-off dyno の動作を確認するには、Heroku にデプロイされているすべてのアプリケーションで利用可能な bash
コマンドを実行します。
$ heroku run bash
Running bash attached to terminal... up, run.1
~ $
この時点で、シェル環境を提供する bash
コマンドを実行している One-off dyno があります。このシェル環境は、ファイルシステムおよびプロセス環境を探索するのに使用できます。
シェルと対話し、デプロイしたファイルをすべて一覧表示します。
~ $ ls
Procfile project.clj src bin ...
bin
ディレクトリにバッチファイルがある場合、その他多くの Unix コマンドのようにこれを実行します。
~ $ echo "Hi there"
Hi there
~ $ pwd
/app
~ $ bin/do-work
ファイルをいくつか削除してから終了します。
~ $ rm Procfile project.clj
~ $ exit
各 dyno には独自の slug アーカイブのコピーが入力されるため、削除されたファイルによって実行中のアプリケーションに変更が加えられることはありません。
Shield Private Space
Shield Private Space を使用している場合、One-off dyno を作成する前に SSH キーをユーザーアカウントに追加します (この処理は 1 回のみ必要です)。
$ heroku keys:add
Generating public/private rsa key pair.
...
$ heroku run bash
...
~ $
One-off dyno の実行構文
heroku run
には 2 種類のパラメータがあります。実行するコマンドを入力することも、アプリケーションの Procfile にあるプロセスタイプを入力することもできます。
スクリプトコマンドまたはアプリケーションで利用可能なその他の実行可能コマンドを入力すると、そのコマンドは追加の引数とともに One-off dyno として実行されます。 たとえば、Python インタープリタを引数として入力されたファイル dowork.py
で実行してから、heroku run python dowork.py
を実行します。
代わりに、Procfile
で宣言されたとおりにプロセスタイプを入力すると、定義が代替され、追加の引数とともに実行されます。 たとえば、以下の Procfile
があるとします。
myworker: python dowork.py
heroku run myworker 42
を実行すると、python dowork.py 42
が One-off dyno として実行されます。
One-off dyno のタイプ
One-off dyno の用途には、以下のようなものがあります。
- データベースの初期化またはデータベース移行の実行 (
rake db:migrate
、node migrate.js migrate
など)。 - コンソールまたは REPL シェルの実行による、任意のコードの実行または本番データベースに対するアプリのモデルの調査 (
rails console
、irb
、node
など)。 - アプリのレポに使用されるワンタイムスクリプト (
ruby scripts/fix_bad_records.rb
、node tally_results.js
など)。
ローカル環境で、アプリのチェックアウトディレクトリ内での直接シェルコマンドによってこれらの One-off dyno を起動します。 たとえば、次のようになります。
コマンドラインフラグを実行中のコマンドに渡すために、実行する文全体を引用して、Heroku CLI によってこのフラグが処理されないようにすることができます: heroku run "rake --help"
$ rake db:migrate
(in /Users/adam/widgets)
== CreateWidgets: migrating ==================================================
-- create_table(:widgets)
-> 0.0040s
== CreateWidgets: migrated (0.0041s) =========================================
まったく同じことを、コマンドに接頭辞 heroku run
を追加して最新の Heroku リリースに対して実行することができます。
$ heroku run rake db:migrate
(in /app)
Migrating to CreateWidgets (20110204210157)
== CreateWidgets: migrating ==================================================
-- create_table(:widgets)
-> 0.0497s
== CreateWidgets: migrated (0.0498s) =========================================
同様に、Rails および rails console
で行うように、コマンドを実行してローカル環境でコンソールを実行できる場合は以下のようになります。
$ rails console
Loading development environment (Rails 3.0.3)
ruby-1.9.2-p136 :001 > Widget.create :name => 'Test'
=> #<Widget id: 1, name: "Test", size: nil, created_at: "2011-05-31 02:36:39", updated_at: "2011-05-31 02:36:39">
同じコマンドをデプロイされた Heroku アプリに実行するとコンソールが実行され、ターミナルに接続されます。
$ heroku run rails console
Running rails console attached to terminal... up, run.2
Loading production environment (Rails 3.0.3)
irb(main):001:0> Widget.create :name => 'Test'
=> #<Widget id: 1, name: "Test", size: nil, created_at: "2011-05-31 02:37:51", updated_at: "2011-05-31 02:37:51">
dyno で実行するコマンドに heroku run
自体が想定しているフラグとの不一致がある場合、--
を使用して、フラグの解析を中止して dyno に渡すように CLI に伝えます。たとえば、dyno で ls -a
を実行する場合、ls
のフラグではなく、アプリ内で渡したかのように -a
が CLI に表示されます。--
で修正するには、次のように行います。
$ heroku run -a myapp -- ls -a
Running ls -a on ⬢ forker... up, run.4520 (Eco)
. .. Procfile server.js
バックグラウンドでのタスク実行
heroku run:detached
を使用して、dyno をバックグラウンドで実行できます。heroku run
とは異なり、これらの dyno では出力がコンソールウィンドウではなくログに送信されます。heroku logs
を使用して、これらのコマンドからの出力を表示できます。
$ heroku run:detached rake db:migrate
Running rake db:migrate... up, run.2
Use 'heroku logs --dyno run.2' to view the log output.
One-off dyno の停止
heroku ps
を使用して、現在実行中の dyno を確認できます。
$ heroku ps
=== run: one-off processes
run.4520: starting 2013/03/13 15:38:08 (~ 1s ago): `bash`
=== web: `bundle exec unicorn -p $PORT -c ./config/unicorn.rb`
web.1: up 2013/03/13 15:08:07 (~ 30m ago)
web.2: up 2013/03/12 17:06:09 (~ 22h ago)
実行中の One-off dyno を停止するには、その dyno の名前で heroku ps:stop
を使用します。
$ heroku ps:stop run.4520
Stopping run.4520 process... done
アプリケーションで heroku ps:restart
を発行すると、One-off dyno は停止しません。One-off dyno はまた、新しいアプリのリリースの後に再起動されません。
One-off dyno のタイムアウト
SIGHUP
が捕捉されず、接続が終了しても dyno が実行され続ける可能性があります。詳細については、シグナルマニュアルのページを参照してください。
One-off dyno への接続は、(入力と出力の両方で) アイドル状態が 1 時間続くと終了します。接続が終了すると、dyno には SIGHUP
が送信されます。このアイドルタイムアウトにより、対話型コンソールセッションを開いて使用しないままにすることによる、意図しない請求の発生が阻止されます。
Shield Space の One-off dyno は、アクティビティがないタイムアウトが 15 分という点で、動作が異なります。
分離されている dyno には接続がないため、タイムアウトがありません。 ただし、すべての dyno と同様、One-off dyno は 24 時間ごとに再起動されます。 つまり、One-off dyno の実行時間は最長で 24 時間となります。
One-off dyno のタイプ
One-off dyno で使用されるデフォルトの dyno タイプは次のように決定されます。
- Eco または Basic dyno タイプを使用しているアプリは、One-off dyno で対応する Eco または Basic dyno タイプを使用します。その他の dyno タイプは使用できません。
- Standard または Performance dyno タイプを使用しているアプリは、One-off dyno で Standard-1X dyno タイプを使用します。これらの dyno タイプを使用するアプリでは、
size
引数を使用して、One-off dyno に異なる dyno タイプを指定できます (heroku run --size=standard-2x rake heavy:job
、heroku run --size=performance-l rake heavy:job
など)。 - Private または Shield dyno タイプを使用しているアプリは、デフォルトでは One-off dyno で Private-M または Shield-M を使用します。
制限
並列で実行できる One-off dyno の数の制限については、「デフォルトのスケーリング制限」セクションを参照してください。
トラブルシューティング
タイムアウト待機プロセス
heroku run
コマンドにより、Heroku への接続がポート 5000 で開きます。ローカルネットワークまたは ISP によってポート 5000 がブロックされている場合、または接続の問題が発生している場合は、以下のようなエラーが表示されます。
$ heroku run rails console
Running rails console attached to terminal...
Timeout awaiting process
Telnet を使用して、ポート 5000 で直接 rendezvous.runtime.heroku.com
に接続できるかどうかを試し、Heroku への接続をテストすることができます。正常なセッションの例は以下のとおりです。
$ telnet rendezvous.runtime.heroku.com 5000
Trying 50.19.103.36...
Connected to ec2-50-19-103-36.compute-1.amazonaws.com.
Escape character is '^]'.
この出力が得られなかった場合、コンピュータによるサービスへのアクセスがブロックされています。この問題を解消するには、貴社の IT 部門、ISP、またはファイアウォールのメーカーに問い合わせることをお勧めします。
SSH 経由での本番 dyno への接続
One-off dyno は管理タスクに最適である反面、本番 dyno でサービスのデバッグを時々行う必要があります。 One-off dyno とは異なり、Heroku Exec では SSH 接続が既存の dyno (web.2 など) に対して直接行われます。Exec では、dyno からのファイルのコピー、ローカルポートのトラフィックの dyno への転送、一般的な Java デバッグツールの利用も可能です。