Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mimic Heroku cli parameters to run > 1 process per app #1

Closed
saidimu opened this issue Jan 13, 2014 · 7 comments
Closed

Mimic Heroku cli parameters to run > 1 process per app #1

saidimu opened this issue Jan 13, 2014 · 7 comments

Comments

@saidimu
Copy link

saidimu commented Jan 13, 2014

Heroku's command-line heroku supports concurrency this way:

heroku ps:scale web=2 worker=3
   Scaling web processes... done, now running 2
   Scaling worker processes... done, now running 3

How feasible is it to implement a slightly modified parameter for this plugin?

Something along the lines of:

dokku:supervisord scale web=2 worker=3
   Scaling web processes... done, now running 2
   Scaling worker processes... done, now running 3

Could this be achieved by using by incrementing/decremnting the numprocs setting in supervisord.conf and then reloading the configuration file by sending a SIGHUP signal to the supervisord process?

@sehrope
Copy link
Owner

sehrope commented Jan 14, 2014

Yes there is actually! The log files are explicitly named with the process number to eventually support something like this (i.e. web.00.log instead of web.log).

Two points I'm looking at first though:

  • How to handle multiple web processes? - Currently Dokku forwards a single port per deployed app. If you have multiple, separate web processes you need to be able to forward traffic to each of them.
  • Where to house the config data for this? - I'm thinking of having an additional file in the Dokku app home directory for it. Something like SCALE. It would have the number of processes of each type to spin up for each process type in the Procfile. It needs to be separate from the command itself so that subsequent deployments via "git push" can reuse the previously set value.

@sehrope
Copy link
Owner

sehrope commented Jan 17, 2014

This has been added to the plugin. The post-release process now checks for a SCALE file in the app's home directory and uses that to determine how many processes of each type to run. If it does not exist then it will default to just one per process type.

You can also also scale via the command line:

dokku scale myapp web=1 worker=4

Everything still runs in the same container though so for web > 1 to work your web processes must be able to share the listening socket (lookup SO_REUSEPORT for how to do this).

Try it out and let me know how it goes!

@sehrope sehrope closed this as completed Jan 17, 2014
@kelvin22
Copy link

kelvin22 commented Aug 1, 2015

Sorry to comment on an old issue...

How exactly do you go about using SO_REUSEPORT?

@sehrope
Copy link
Owner

sehrope commented Aug 1, 2015

How exactly do you go about using SO_REUSEPORT?

It's a socket option when you're creating a server socket that listens on a port. The specifics of how to configure it will depend on your programming language. Your best bet is to do a search for it plus your language/framework for a working example.

@kelvin22
Copy link

kelvin22 commented Aug 1, 2015

So on a nginx (dokku's), gunicorn, flask, Python stack, would it be handled
by gunicorn? Seems like each of those supports it in some form.

On Saturday, 1 August 2015, Sehrope Sarkuni notifications@github.com
wrote:

How exactly do you go about using SO_REUSEPORT?

It's a socket option when you're creating a server socket that listens on
a port. The specifics of how to configure it will depend on your
programming language. Your best bet is to do a search for it plus your
language/framework for a working example.


Reply to this email directly or view it on GitHub
#1 (comment)
.

@sehrope
Copy link
Owner

sehrope commented Aug 1, 2015

You wouldn't have to touch nginx. I think it also supports that option but it's outside the scope of what I'm describing here.

Using the option within a dokku app is to allow for separate web processes to listen on the same port. That way when nginx forwards a web request to your app, it can be processed by any one of the processes. Without the SO_REUSEPORT option, whichever web process binds to the port first will "win" and the rest will be rejected from listening on it as it's already in use.

Note that it's probably simpler to use a web stack that handles this internally without SO_REUSEPORT and stick to web=1. For example gunicorn supports forking multiple processes and will automatically handle them listening on the same port.

@kelvin22
Copy link

kelvin22 commented Aug 3, 2015

Thanks @sehrope, your comments gave me the direction I needed to research. There isn't always much information on how all the components of the web stack interact. I've now got a deeper understanding, and have taken on board your suggested gunicorn method of handling multiple processes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants