Skip to content

Added flexible customization of gunicorn via environment variables #2813

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

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

Peopl3s
Copy link
Contributor

@Peopl3s Peopl3s commented May 16, 2025

Added flexible customization of gunicorn via environment variables.

1. Flexibility and Environment-Based Configuration
Allows dynamic parameter changes via the GUNICORN_WSGI_SETTINGS environment variable, making it suitable for different environments (dev/stage/prod) and Docker deployments.

2. Comprehensive Configuration
Includes all major Gunicorn parameters with clear default values (GUNICORN_WSGI_DEFAULTS).

3. Documentation and Clarity
Detailed comments with links to Gunicorn’s official documentation.
Usage examples and parameter explanations.

4. Advanced Worker Settings
Fine-tuned worker management (worker_class, threads, worker_connections).
Logging customization (access_log_format, loglevel).
Timeout controls (timeout, graceful_timeout, keepalive).
The second file lacks these options.

5. Production Optimization
Supports preload_app, max_requests_jitter, and worker_tmp_dir (for tmpfs).

Copy link
Contributor

@anywindblows anywindblows left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we implement the functionality of changing the configuration parameters of gunicorn, then it seems to me that it is necessary to correct/add the following:

  1. The documentation of the wemake-django-template project
  2. In my opinion, the parameters in .env should be stored not as a dictionary, but as a set, so it will be consistent.
  3. _load_gunicorn_settings - must receive keys from .env with the prefix GUNICORN_

@sobolevn Do you think it's worth discussing?

'loglevel': 'info',
'preload_app': False,
'wsgi_app': 'server.wsgi.application',
'workers': 1,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to use multiprocessing.cpu_count() * 2 + 1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A valid point. Thanks. Waiting for @sobolevn feedback.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please.

)


GUNICORN_WSGI_DEFAULTS: MappingProxyType[str, Any] = MappingProxyType({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's better to use a structure with attributes and load default values using getattr()

Copy link
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, the use-case is not really clear for me. Why do you want to have different gunicorn settings? They always must be the same. Otherwise, different envs might behave in a different way.

Also question: how do you want env change to work? I will still have to reload gunicorn for changes to make effect.

'loglevel': 'info',
'preload_app': False,
'wsgi_app': 'server.wsgi.application',
'workers': 1,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please.

@Peopl3s
Copy link
Contributor Author

Peopl3s commented May 18, 2025

Sorry, the use-case is not really clear for me

@sobolevn The idea was more along the following lines: to make it easier to adjust Gunicorn settings in production without creating a pull request and editing config files. Just restart the deployment job in CI/Kubernetes pod (or let Kube itself update the env after some time).

Perhaps such tricks are excessive for this template. Still, I wanted to suggest it—maybe something useful could come out of it. :)

@PrimeStr
Copy link

to make it easier to adjust Gunicorn settings in production without creating a pull request and editing config files.

I am not a contributor, but I agree with the point.
Indeed, sometimes there are moments when it is necessary to change the settings of the gunicorn "on the fly".
It is possible to live without this feature, but it would be a little easier with it.

)

# https://docs.gunicorn.org/en/22.0.0/settings.html#bind
bind = GUNICORN_WSGI_SETTINGS.get('bind', GUNICORN_WSGI_DEFAULTS['bind'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question / idea. Maybe we can use module level __getattr__ to get needed attributes?

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

Successfully merging this pull request may close these issues.

4 participants