Procfile

A Procfile is a plain-text file in your repo's root that declares one process type per line. Same format as Heroku — most projects can copy theirs over unchanged.

Format

<process-type>: <command>

Each line is one process type. Process types are independent: web serves HTTP, worker consumes background jobs, queue-specific processes drain Sidekiq queues. Each runs in its own container, scales independently.

Minimal example (Node)

web: npm start

Rails with Sidekiq queues

web: bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq
release: bundle exec rails ci:release
inventory_updates: bundle exec sidekiq -q inventory_updates
order_processing: bundle exec sidekiq -q order_processing -c 4
reports: bundle exec sidekiq -q reports -c 1

The web process is special

Your web command must bind to $PORT. The stack's nginx routes external HTTP/HTTPS to whatever port that env var supplies.

web: node server.js                     # server.js: app.listen(process.env.PORT)
web: bundle exec puma -p $PORT
web: gunicorn app:app --bind 0.0.0.0:$PORT
web: serve -s dist -l tcp://0.0.0.0:$PORT
Hardcoded ports break the deploy

If your web command binds to a fixed port (e.g. 3000) instead of $PORT, healthchecks fail and the deploy is rolled back. The error usually says port listening check: unable to enter the container or similar.

The release process

If you declare a release: command, dokku runs it once after each successful build, before swapping traffic. Typical use: database migrations.

release: bundle exec rails db:migrate
release: ./bin/rails db:migrate
release: alembic upgrade head

If release exits non-zero, the deployment fails and the previous container keeps serving traffic. Your code is on the new SHA, but no users see it. See Deploy failures when this happens unexpectedly.

Scaling

Procfile only declares the process types — it does not set how many of each run. Counts are managed separately.

$ ownstack ps:scale <app> worker=2 web=1   # once shipped — see issue #294
$ ssh dokku@<stack-ip> ps:scale <app> worker=2   # manual today

See Scaling for the full story, including why app.json's formation block can block manual scaling.

One-off commands

To run a one-off command (not declared in Procfile) inside a fresh container of the running image:

$ ownstack remote run <app> rails console
$ ownstack remote run <app> bin/rails db:migrate:status
$ ssh dokku@<stack-ip> run <app> bash
Note

Process names are case-sensitive and conventionally lowercase. Dokku passes the type name verbatim to the container as the process command's argv[0].