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
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
Process names are case-sensitive and conventionally lowercase. Dokku passes the type name verbatim to the container as the process command's argv[0].
Read next
- Config vars — env vars all processes share.
- Scaling processes — change instance counts.
- Healthchecks — how dokku decides a deploy is good.