One-off Admin Processes

Last Updated: 07 February 2012

Table of Contents

The set of processes declared in your Procfile and run via heroku scale are known as the process formation. These processes do the app’s regular business (such as handling web requests and processing background jobs) as it runs. But when you wish to do one-off administrative or maintenance tasks for the app, you’ll want a one-off process.

One-off processes

After you push your application to Heroku, the slug compiler generates a slug archive containing the application. The application may contain many components, including a web server, a console application, and scripts to initialize the database.

While the web process would be defined as a process type in the Procfile, the console and script would only be executed when needed. These are one-off processes.

Difference between formation dynos and one-off processes

One-off processes execute as a dyno, exactly like the app’s web, worker, and other formation processes. They get all the benefits of dyno isolation.

Each one-off process gets its own ephemeral filesystem, not shared with any other dyno, that is discarded as soon as you disconnect. This filesystem is populated with the slug archive - so one-off processes can make full use of anything deployed in the application.

There are four differences between one-off dynos run with heroku run and formation dynos run with heroku scale:

  • One-off dynos run attached to your terminal, with a character-by-character TCP connection for STDIN and STDOUT. This allows you to use interactive processes like a console. Since STDOUT is going to your terminal, the only thing recorded in the app’s logs is the startup and shutdown of the dyno.
  • One-off dynos terminate as soon as you press Ctrl-C or otherwise disconnect in your local terminal. One-off dynos never automatically restart, whether the process ends on its own or whether you manually disconnect.
  • One-off dynos are named in the scheme run.N rather than the scheme worker.N.
  • One-off dynos can never receive HTTP traffic, since the routing mesh only routes traffic to processes named web.N.

Other than these differences, the dyno manifold makes no other distinction between one-off dynos and formation dynos.

Running a one-off process

One-off processes can be created using heroku run. To see one-off processes in action, execute the bash command, available in all applications deployed to Heroku:

$ heroku run bash
Running bash attached to terminal... up, run.1
~ $

At this point you have a process running as a one-off dyno, and the process is executing the bash command - which provides a shell environment that can be used to explore the file system and process.

Interact with the shell and list all the files that you deployed:

~ $ ls
Procfile project.clj src bin ...

If you had a batch file in the bin directory, you can simply execute it, just as you can many other unix commands:

~ $ echo "Hi there"
Hi there
~ $ pwd
/app
~ $ bin/do-work

Remove a few files, and exit:

~ $ rm Procfile project.clj
~ $ exit

Because each one-off process is populated with its own copy of the slug-archive, the deleted files won’t change your running application.

Example one-off processes

Some types of one-off processes include:

  • Initialising databases or running database migrations. (e.g. rake db:migrate or node migrate.js migrate)
  • Running a console (also known as a REPL shell) to run arbitrary code or inspect the app’s models against the live database. (e.g. rails console, irb, or node)
  • One-time scripts committed into the app’s repo (e.g. ruby scripts/fix_bad_records.rb or node tally_results.js).

In your local environment, you invoke these one-off processes by a direct shell command inside the app’s checkout directory. For example:

To pass command line flags to the command being executed, you can quote the entire string to be executed to avoid the Heroku CLI processing the flags: heroku run "rake --help"

$ rake db:migrate
(in /Users/adam/widgets)
==  CreateWidgets: migrating ==================================================
-- create_table(:widgets)
   -> 0.0040s
==  CreateWidgets: migrated (0.0041s) =========================================

You can do the exact same thing, but run against your latest Heroku release out on the dyno manifold, by prefixing your command with heroku run:

$ heroku run rake db:migrate
(in /app)
Migrating to CreateWidgets (20110204210157)
==  CreateWidgets: migrating ==================================================
-- create_table(:widgets)
   -> 0.0497s
==  CreateWidgets: migrated (0.0498s) =========================================

Likewise, if you can run a console in your local environment by executing a command, as you can with Rails and rails console command:

$ 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">

Running the same command against your deployed Heroku app will execute it, and attach it to your terminal:

$ 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">

Running tasks in background

You can run a process in the background using heroku run:detached. Unlike heroku run, these processes will send their output to your logs instead of your console window. You can use heroku logs to view the output from these commands:

$ heroku run:detached rake db:migrate
Running rake db:migrate... up, run.2
Use 'heroku logs -p run.2' to view the log output.

Stopping running processes

One-off processes will stay running even if you lose your Internet connection to Heroku. Interactive consoles may stay active depending on whether a disconnect signal was received. Closing your console after you are finished using them and running heroku ps if you lose your connection to the console is the best way to ensure the console has terminated.

You can check your current running processes using heroku ps:

$ heroku ps
Process  State            Command                               
-------  ---------------  ------------------------------------  
run.1    running for 3s   bundle exec rake db:migrate           
web.1    up for 23h       bundle exec thin start -e $RACK_EN..  
web.2    up for 22h       bundle exec thin start -e $RACK_EN..  

If you wish to stop a running process, use heroku ps:stop with the name of the process you want to stop:

$ heroku ps:stop run.1
Stopping run.1 process... done

Troubleshooting

Timeout awaiting process

The heroku run process opens a connection to Heroku on port 5000. If your local network or ISP is blocking port 5000, or you are experiencing a connectivity issue, you will see an error similar to:

$ heroku run rails console
Running rails console attached to terminal... 
Timeout awaiting process

You can test your connection to Heroku by trying to connect directly to port 5000 by using telnet to rendezvous.heroku.com. A successful session will look like this:

$ telnet s1.runtime.heroku.com 5000
Trying 107.20.246.116...
Connected to ec2-107-20-246-116.compute-1.amazonaws.com.
Escape character is '^]'. 

If you do not get this output, your computer is being blocked from accessing our services. We recommend contacting your IT department, ISP, or firewall manufacturer to move forward with this issue.

Frequently Asked Questions

SSH Access

Since your app is spread across many servers in the dyno manifold, there is no single place to SSH into. In short, forget servers.

You can invoke a shell as a one-off process:

$ heroku run bash
~ $
>> `pwd`
=> "/app"

However, there is little to be gained from doing so. The filesystem is ephemeral (each process has its own copy of the slug), and each command may run on a different virtual machine.

When you find yourself wanting SSH access, there’s probably a better approach that properly accounts for Heroku’s distributed environment.

  • The heroku command line tool supports most operations you would perform with SSH in traditional hosting environments.
  • One-off processes can be used to execute code (for example, database initialisation) in your application.