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

How to make django-environ work with uwsgi emperor? #58

Closed
tiany opened this issue Dec 3, 2015 · 20 comments
Closed

How to make django-environ work with uwsgi emperor? #58

tiany opened this issue Dec 3, 2015 · 20 comments
Labels
question Further information is requested

Comments

@tiany
Copy link

tiany commented Dec 3, 2015

I use this project with my django projection, deployed by uwsgi(emperor mode) + nginx, it worked well, thanks for your working, but when i touch the uwsgi config file, the env vars will not reload, for now, i can send signal 3 to the process which served my django app,, is there any good ways to make this done?

(sorry for my poor english...

@joke2k
Copy link
Owner

joke2k commented Dec 25, 2015

Hi @tiany don't worry about your english, mine seems worse than your ;)

About your question, i'm using uwsgi too and when i touch con uwsgi file the environment variables is correctly reloaded.
Can you post more information like where do you use Env.read_env() and which variables do you want to load?

@joke2k joke2k added the question Further information is requested label Dec 25, 2015
@gopar
Copy link

gopar commented Feb 28, 2016

Had something similar @tiany

What was happening to me was that environ was looking for the file in a different directory other than the project. This is how I fixed it.

import os                                                                                                
environ.Env.read_env(os.path.join(os.getcwd(), ".env"))  

@tiany
Copy link
Author

tiany commented Feb 29, 2016

@gopar so your problem is when you start your project, no variable is loaded? I think mine is a little different, it can load all variables, but when i changed the env file and touch uwsgi.ini, uwsgi worker process restarted but all env variables is still the old ones.

@joke2k i wrote the Env.read_env in my project settings.py, env file was putted in the project root directory.

the process is like this:

  1. all project goes well, ps -ef | grep uwsgi shows this:

    root     11631     1  0  2015 ?        00:02:12 /usr/local/bin/uwsgi --master --die-on-term --emperor /etc/uwsgi/apps-enabled
    root     14113 11631  0 Jan21 ?        00:01:19 /usr/local/bin/uwsgi --master --die-on-term --emperor /etc/uwsgi/apps-enabled
    www-data 15151 14113  0 Feb25 ?        00:00:38 /usr/local/bin/uwsgi --ini myapp_uwsgi.ini
    www-data 21437 15151  0 16:48 ?        00:00:00 /usr/local/bin/uwsgi --ini myapp_uwsgi.ini
    tiany    21568 15889  0 16:50 pts/4    00:00:00 grep --color=auto uwsgi
    
  2. I change the env var in myapp.env file, and touch myapp_uwsgi.ini, after this, ps -ef | grep uwsgi shows this:

    root     11631     1  0  2015 ?        00:02:12 /usr/local/bin/uwsgi --master --die-on-term --emperor /etc/uwsgi/apps-enabled
    root     14113 11631  0 Jan21 ?        00:01:19 /usr/local/bin/uwsgi --master --die-on-term --emperor /etc/uwsgi/apps-enabled
    www-data 15151 14113  0 Feb25 ?        00:00:39 /usr/local/bin/uwsgi --ini myapp_uwsgi.ini
    www-data 21996 15151  0 16:54 ?        00:00:00 /usr/local/bin/uwsgi --ini myapp_uwsgi.ini
    tiany    22005 15889  0 16:54 pts/4    00:00:00 grep --color=auto uwsgi
    
  3. after this, if i add some new env vars, that can be accessed in my code, but the exist env var will still be with the old value, not updated.

from my research, I can got the env from process 15151, and after touch that process not restarted so the env is not reloaded, either. if i killed pid 15151 all worked.

for now, I write a script to kill this pid, I'd want to find one grace way to do this.

Thanks a lot.

@QasimK
Copy link

QasimK commented May 27, 2016

@joke2k I have encountered the same issue as @tiany: touching the .ini file will not load the new values if the variables have been altered in my .env file

@max-arnold
Copy link
Contributor

@joke2k I have the same issue with v0.4.0. It looks like logical consequence of the following design decisions:

  1. Environment is kept in os.environ (and not in Env instance state)
  2. There are multiple levels of inheritance: Improve documentation for read_env() #88
  3. Inheritance is handled via https://docs.python.org/3/library/stdtypes.html#dict.setdefault, which won't touch any value if it is already exists

uWSGI reload-os-env = true does not help.

max-arnold added a commit to innoteq/django-environ that referenced this issue Jan 10, 2017
max-arnold added a commit to innoteq/django-environ that referenced this issue Jan 10, 2017
@max-arnold
Copy link
Contributor

@max-arnold
Copy link
Contributor

@tiany @QasimK Could you please test this patch? #105

@QasimK
Copy link

QasimK commented Jan 30, 2017

@max-arnold I will test it soon. Although I am not running in uwsgi-emperor mode, from the looks of it this should resolve the issue that I was having.

@QasimK
Copy link

QasimK commented Feb 6, 2017

@max-arnold I can confirm that #105 resolves this issue for me 😄

@max-arnold
Copy link
Contributor

max-arnold commented Mar 9, 2017

@joke2k Daniele, any chances for this PR (#105) to be merged? The problem seems to be fixed, unit tests pass.

@joke2k
Copy link
Owner

joke2k commented Apr 13, 2017

merged! thank you for debugging

@matteosimone
Copy link

I am seeing this issue on 0.4.4. I looked into the changes that resulted from this pr and these fixes were reverted. When I do a uwsgi reload after changing a .env file, the new settings are not pulled in from the file. Is anyone else having this issue?

@matteosimone
Copy link

matteosimone commented Jan 16, 2018

Hi , for anyone else who runs into this problem:

If you do not care about environment variables taking priority over variables in .env files, then you can fix this problem by overriding read_env() and have it always overwrite existing keys instead of using cls.ENVIRON.setdefault. This seems to work correctly for my use case, please let me know if you know of any flaws with this approach (aside from changing the expected priority behavior).

@QasimK
Copy link

QasimK commented Mar 28, 2018

@matteosimone How do you override read_env()? Do you use your own fork of the package?

@matteosimone
Copy link

@QasimK make a subclass of Env and use it instead of importing from the django-environ package

It might look something like

import environ

class Env(environ.Env):
    @classmethod
    def read_env(cls, env_file=None, **overrides):
        # Make your own implementation based off the original ..

@khink
Copy link

khink commented Mar 29, 2019

I am still experiencing a problem that looks similar to this one.

We are using django-environ 0.4.5, which should have the #105 fix.

The problem is: touching the uwsgi-reload file does reload production.py (our Django settings file used on this environment), but the .env variables are not updated.

What i mean by this is, when is put MY_SETTING = 2 # or any number in the production.pysettings file, uwsgi-reload updates the value.

But if i use MY_SETTING = env.int('MY_SETTING'), where my .env contains MY_SETTING=2, the reload doesn't change the value if i change it to another number in .env. I see the same thing for an env.bool() setting.

The .env file has been loaded correctly at some point, probably when the uwsgi processes were killed and restarted (instead of reloaded).

Not sure is it matters, but we have master = true in the uwsgi.ini file.

To make sure the path to .env was correct, i also tried putting the full path to the env file in read_env: environ.Env.read_env('/opt/apps/my_django_project/.../settings/.env')

I'm not sure if i'm doing something wrong, or the fix (#105) doesn't cover our case. How could i debug this further?

@max-arnold
Copy link
Contributor

@khink AFAIK, #105 was rolled back as it caused other problems

@khink
Copy link

khink commented Mar 29, 2019

@max-arnold Thanks for your speedy reply. You seem to be right, there's a revert commit: 0482931

@joke2k Maybe this ticket could be re-opened, if the fix was reverted?

@mattaw
Copy link

mattaw commented May 7, 2019

Please take a look at #225 as it should fix this properly, making django-environ use a copy of the environment instead of the os.environ mapper class.

@duwensi-bgi
Copy link

Please pay attention to here: environ.Env.read_env('/path/to/.env')
When reloading uwsgi process, the read_env method read the env file again indeed. But all existing variables in env file will not be updated because the argument overwrite of read_env method is False by default. That is the reason.

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

No branches or pull requests

9 participants