Fly Secrets and Python Decouple

Hello there,

I’m deploying a python + django app and I’m using Python Decouple lib for env configuration.

I’m used to it and it reads from the enviromnet variables or from the .env file.

I assumed that the Fly Secrets were loaded as env var, but it seems to no be working.

I did the same on Heroku on the past and it worked, so I imagine that it should be similar.

Also, when I add my .env in the deploy it work, so the Python Decouple is working.

Do I need to add some step in the dockerfile or fly.toml to load the secrets?

Thanks.

You might be able to debug this by running fly ssh console -C env, to see what environment variables are set in your running vm.
For what it’s worth, secrets should be exposed as normal environment variables to running apps, so it sounds like this setup should Just Work.

1 Like

It show the secrets that I have set, but when I run fly deploy without the .env file the depoly fail with a error message saying that the SECRET_KEY was not found in the env var.

Okay. So, to clarify things:

  1. If you run fly ssh console -C env, you see your secrets.
  2. If your secret is in the .env file, everything works.
  3. Your deploy is failing.

Is it failing while building a docker image? Docker builders, IIRC, do not have access to secrets. Release commands and running apps do, but not docker builders.

If you feel comfortable doing this, posting information like logs of failed commands (obviously not the output of env though!!) might get you more help as well.

1 Like
  1. Yes, I can see my secrets.
  2. When I deploy with my .env file the deploy and app works fine
  3. If I deploy without my .env file, it fails.

Reading the errors again, it seems that the docker build was already finished and it broke in the next step of deploy. Specifically in the RUN python manage.py collectstatic --noinput step.

See the full console log:

Platform: nomad
✓ Configuration is valid
--> Verified app config
==> Building image
Remote builder fly-builder-holy-rain-5761 ready
==> Creating build context
--> Creating build context done
==> Building image with Docker
--> docker host: 20.10.12 linux x86_64
[+] Building 7.7s (0/1)                                                                                                                                       
[+] Building 5.6s (10/10) FINISHED                                                                                                                            
 => [internal] load remote build context                                                                                                                 0.0s
 => copy /context /                                                                                                                                      1.1s
 => [internal] load metadata for docker.io/library/python:3.10-slim-buster                                                                               1.5s
 => [1/7] FROM docker.io/library/python:3.10-slim-buster@sha256:7d6283c08f546bb7f97f8660b272dbab02e1e9bffca4fa9bc96720b0efd29d8e                         0.0s
 => CACHED [2/7] RUN mkdir -p /code                                                                                                                      0.0s
 => CACHED [3/7] WORKDIR /code                                                                                                                           0.0s
 => CACHED [4/7] COPY requirements.txt /tmp/requirements.txt                                                                                             0.0s
 => CACHED [5/7] RUN set -ex &&     pip install --upgrade pip &&     pip install -r /tmp/requirements.txt &&     rm -rf /root/.cache/                    0.0s
 => [6/7] COPY . /code/                                                                                                                                  0.9s
 => ERROR [7/7] RUN python manage.py collectstatic --noinput                                                                                             1.2s
------                                                                                                                                                        
 > [7/7] RUN python manage.py collectstatic --noinput:                                                                                                        
#10 1.166 Traceback (most recent call last):                                                                                                                  
#10 1.166   File "/code/manage.py", line 22, in <module>                                                                                                      
#10 1.166     main()                                                                                                                                          
#10 1.166   File "/code/manage.py", line 18, in main
#10 1.166     execute_from_command_line(sys.argv)
#10 1.166   File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
#10 1.167     utility.execute()
#10 1.167   File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 386, in execute
#10 1.167     settings.INSTALLED_APPS
#10 1.167   File "/usr/local/lib/python3.10/site-packages/django/conf/__init__.py", line 92, in __getattr__
#10 1.168     self._setup(name)
#10 1.168   File "/usr/local/lib/python3.10/site-packages/django/conf/__init__.py", line 79, in _setup
#10 1.168     self._wrapped = Settings(settings_module)
#10 1.168   File "/usr/local/lib/python3.10/site-packages/django/conf/__init__.py", line 190, in __init__
#10 1.168     mod = importlib.import_module(self.SETTINGS_MODULE)
#10 1.168   File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module
#10 1.168     return _bootstrap._gcd_import(name[level:], package, level)
#10 1.168   File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
#10 1.168   File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
#10 1.168   File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
#10 1.168   File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
#10 1.168   File "<frozen importlib._bootstrap_external>", line 883, in exec_module
#10 1.169   File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
#10 1.169   File "/code/dpj/settings.py", line 25, in <module>
#10 1.169     SECRET_KEY = config('SECRET_KEY')
#10 1.169   File "/usr/local/lib/python3.10/site-packages/decouple.py", line 248, in __call__
#10 1.169     return self.config(*args, **kwargs)
#10 1.169   File "/usr/local/lib/python3.10/site-packages/decouple.py", line 107, in __call__
#10 1.169     return self.get(*args, **kwargs)
#10 1.169   File "/usr/local/lib/python3.10/site-packages/decouple.py", line 92, in get
#10 1.170     raise UndefinedValueError('{} not found. Declare it as envvar or define a default value.'.format(option))
#10 1.170 decouple.UndefinedValueError: SECRET_KEY not found. Declare it as envvar or define a default value.
------
Error failed to fetch an image or build from source: error building: executor failed running [/bin/sh -c python manage.py collectstatic --noinput]: exit code: 1

Not sure when the secrets are loaded in the env var.

I think the problem is that Fly’s secrets are only available when the app is running, not during the build (edit: as @allison already pointed out).

You can create build-time secrets, but it’s a little complicated: Build Secrets · Fly Docs

Alternatively, if the values are not sensitive, you can set build-time environment variables in fly.toml using build arguments.

1 Like

That python command is the last step of your Dockerfile. The all-caps RUN there is docker syntax. So yeah, what tom93 said is totally correct! Your problem is that you need to configure a build secret.

I really hope that gets you up and running! If you still run into trouble, though, feel free to post again