Where do I set environment variables on my Django Digital Ocean server? - python

I'm running my Django project on my Ubuntu 16.04 Digital Ocean server running Gunicorn/Nginx. I have my whole project except my settings.py file so am looking do add that in now - however don't want to hardcode the SECRET_KEY - so am looking to define an environment variable like it says in the Django docs: SECRET_KEY = os.environ['SECRET_KEY'].
Where do I define this variable? Is it in my gunicorn config file (/etc/systemd/system/gunicorn.service)

You can create environmental variables inside your .bashrc file in your home folder.
Just open the .bashrc file from home folder
sudo vi ~/.bashrc
And then at the end of the file, add your variable
export SECRET_KEY='your secret key'
then save it, and try running source command on the file so as to enable the variable(So that it gets applied without restarting the system)
source ~/.bashrc

Related

Heroku Python Local Environment Variables

Working on a heroku django project.
Goal: I want to run the server locally with same code on cloud too (makes sense).
Problem:
Environments differ from a linux server (heroku) to a local PC windows system.
Local environment variables differ from cloud Heroku config vars.
Heroku config vars can be setup easily using the CLI heroku config:set TIMES=2.
While setting up local env vars is a total mess.
I tried the following in cmd:
py -c "import os;os.environ['Times']=2" # To set an env var
Then ran py -c "import os;os.environ.get('Times','Not Found')" stdout: "Not Found".
After a bit of research it appeared to be that such env vars are stored temporarily per process/session usage.
Solution theory: Redirect os.environ to .env file of the root heroku project instead of the PC env vars. So I found this tool direnv perfect for Unix-like OSs but not available for Windows.
views.py code (runs perfect on cloud, sick on the local machine):
import os
import requests
from django.shortcuts import render
from django.http import HttpResponse
from .models import Greeting
def index(request):
# get method takes 2 parameters (env_var_string,return value if var is not found)
times = int(os.environ.get('TIMES',3))
return HttpResponse('<p>'+ 'Hello! ' * times+ '</p>')
def db(request):
greeting = Greeting()
greeting.save()
greetings = Greeting.objects.all()
return render(request, "db.html", {"greetings": greetings})
Main Question: Is there a proper way to hide secrets locally in windows and access them by os.environ['KEY']?
Another solution theory: I was wondering if a python virtual environment has it's own environment variables. If yes i activate a venv locally without affecting the cloud. Therefore os.environ['KEY'] is redirected to the venv variables. Again it's just a theory.
You can use environment variables which you can get via os.environ['KEY'].
The same code will work on both local development and on Heroku.
On Heroku define these variables using ConfigVars heroku config:set KEY=val while locally (on Windows for example) define the same variables in an .env file (use dotenv to load them). The .env file is never committed with the source code.

Saleor front-end installation

I am trying to install saleor front-end package from github.The documentation is outdated and i get an error when i try
>>>nmp start
Error: Environment variable API_URI not set
I found this variable in different places but did not know what to change, and where to set it
EDIT:Solved.just in case somebody is going through the same problem
in webpack>config.base.js
process.env.API_URI = 'http://localhost:8000/graphql/'
On Linux, I fixed this by setting environment variable before running npm; start with:
export API_URI=http://localhost:8000/graphql/
on the terminal.
create a file in the root directory of /saleor-storefront called ".env" and write inside:
API_URI=http://localhost:8000/graphql/
This will create an environment variable called API_URI with the value 'http://localhost:8000/graphql/'
Create .env file in a root directory or set environment variables with following values:
API_URI (required) - URI of a running instance of Saleor GraphQL API. If you are running Saleor locally with the default settings, set API_URI to: http://localhost:8000/graphql/.
APP_MOUNT_URI - URI at which the Dashboard app will be mounted. E.g. If you set APP_MOUNT_URI to /dashboard/, your app will be mounted at http://localhost:9000/dashboard/.
STATIC_URL - URL where the static files are located. E.g. if you use S3 bucket, you should set it to the bucket's URL. By default Saleor assumes you serve static files from the root of your site at http://localhost:9000/.
Saleor on Github: How to configure the Dashboard

Selecting the correct settings file to use in Django

I'm following the approach in Two Scoops of Django: Best Practices for Django 1.6 regarding multiple settings files. I'm using Django 1.7 and virtualenvwrapper.
My setup is as follows:
project/
app1/
app2/
project/
__init__.py
settings/
__init__.py
base.py
local.py
production.py
manage.py
I'm a bit confused as to how Django knows which settings file to use. I do not want to specify the settings file every time I run manage.py. I would rather like to set the DJANG_SETTINGS_MODULE environmental variable as explained in omouse anser here:
What confuses me is in the wsgi.py file there is a line:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings.production")
Is this file only used in the production server? What happens if I already have a DJANGO_SETTINGS_MODULE environmental variable defined on the server?
When running it locally, I understand I need to set the DJANGO_SETTINGS_MODULE env variable every time I open the console. I've read here that I can define a postactivate hook in virtualenvwrapper. This hook will then create the environmental variables that I require everytime I activate the environment.
Is this the recommended way of ensuring the correct DJANGO_SETTINGS_MODULE env variable is loaded on my local machine? Would I also need to setup a similar file on my hosting server? I'm planning on using PythonAnywhere for hosting.
Lastly, if I run a staging server, how would I tell Django to load the staging settings file? The staging server is the practically the same as the production server, so I guess need a different wsgi.py file for the staging server, but that seems like a anti-pattern.
os.environ.setdefault only sets the value if it is not set. When you run in production, export the environment variable DJANGO_SETTINGS_MODULE and set it to your production/staging settings file, and you don't have to set anything when running in development (if you set it by default to your development settings). This is the DRY-est method.
The method with a local_settings.py (which is most of the times kept out of the repo!) is not best practice and should be avoided.

Setting NewRelic environment on Dotcloud (Python)

I have a Python application that is set up using the new New Relic configuration variables in the dotcloud.yml file, which works fine.
However I want to run a sandbox instance as a test/staging environment, so I want to be able to set the environment of the newrelic agent so that it uses the different configuration sections of the ini configuration. My dotcloud.yml is set up as follows:
www:
type: python
config:
python_version: 'v2.7'
enable_newrelic: True
environment:
NEW_RELIC_LICENSE_KEY: *****************************************
NEW_RELIC_APP_NAME: Application Name
NEW_RELIC_LOG: /var/log/supervisor/newrelic.log
NEW_RELIC_LOG_LEVEL: info
NEW_RELIC_CONFIG_FILE: /home/dotcloud/current/newrelic.ini
I have custom environment variables so that the sanbox is set as "test" and the live application is set to "production"
I am then calling the following in my uswsgi.py
NEWRELIC_CONFIG = os.environ.get('NEW_RELIC_CONFIG_FILE')
ENVIRONMENT = os.environ.get('MY_ENVIRONMENT', 'test')
newrelic.agent.initialize(NEWRELIC_CONFIG, ENVIRONMENT)
However the dotcloud instance is already enabling newrelic because I get this in the uwsgi.log file:
Sun Nov 18 18:50:12 2012 - unable to load app 0 (mountpoint='') (callable not found or import error)
Traceback (most recent call last):
File "/home/dotcloud/current/wsgi.py", line 15, in <module>
newrelic.agent.initialize(NEWRELIC_CONFIG, ENVIRONMENT)
File "/opt/ve/2.7/local/lib/python2.7/site-packages/newrelic-1.8.0.13/newrelic/config.py", line 1414, in initialize
log_file, log_level)
File "/opt/ve/2.7/local/lib/python2.7/site-packages/newrelic-1.8.0.13/newrelic/config.py", line 340, in _load_configuration
'environment "%s".' % (_config_file, _environment))
newrelic.api.exceptions.ConfigurationError: Configuration has already been done against differing configuration file or environment. Prior configuration file used was "/home/dotcloud/current/newrelic.ini" and environment "None".
So it would seem that the newrelic agent is being initialised before uwsgi.py is called.
So my question is:
Is there a way to initialise the newrelic environment?
The easiest way to do this, without changing any code would be to do the following.
Create a new sandbox app on dotCloud (see http://docs.dotcloud.com/0.9/guides/flavors/ for more information about creating apps in sandbox mode)
$ dotcloud create -f sandbox <app_name>
Deploy your code to the new sandbox app.
$ dotcloud push
Now you should have the same code running in both your live and sandbox apps. But because you want to change some of the ENV variables for the sandbox app, you need to do one more step.
According to this page http://docs.dotcloud.com/0.9/guides/environment/#adding-environment-variables there are 2 different ways of adding ENV variables.
Using the dotcloud.yml's environment section.
Using the dotcloud env cli command
Whereas dotcloud.yml allows you to define different environment variables for each service, dotcloud env set environment variables for the whole application. Moreover, environment variables set with dotcloud env supersede environment variables defined in dotcloud.yml.
That means that if we want to have different values for our sandbox app, we just need to run a dotcloud env command to set those variables on the sandbox app, which will override the ones in your dotcloud.yml
If we just want to change on variable we would run this command.
$ dotcloud env set NEW_RELIC_APP_NAME='Test Application Name'
If we want to update more then one at a time we would do the following.
$ dotcloud env set \
'NEW_RELIC_APP_NAME="Test Application Name"' \
'NEW_RELIC_LOG_LEVEL=debug'
To make sure that you have your env varibles set correctly you can run the following command.
$ dotcloud env list
Notes
The commands above, are using the new dotCloud 0.9.x CLI, if you are using the older one, you will need to either upgrade to the new one, or refer to the documentation for the old CLI http://docs.dotcloud.com/0.4/guides/environment/
When you set your environment variables it will restart your application so that it can install the variables, so to limit your downtime, set all of them in one command.
Unless they are doing something odd, you should be able to override the app_name supplied by the agent configuration file by doing:
import newrelic.agent
newrelic.agent.global_settings().app_name = 'Test Application Name'
Don't call newrelic.agent.initialize() a second time.
This will only work if app_name is listing a single application to report data to.

Deploying Django application on Webfaction

This is the first time I am trying to deploy my django project (myproject) on Webfaction.
My project dir-structure is as follows:
In webapps/django: myproject.wsgi, myproject
settings.py is at myproject/src/myproject/
Under such circumstances, how should I define DJANGO_SETTINGS_MODULE in myproject.wsgi?
For the default installation by webfaction, it is defined as myproject.settings. Should I be defining DJANGO_SETTINGS_MODULE as myproject.src.myproject.settings?
When you setup a Django project on webfaction, you get a file structure like so:
~ (your home directory)
+webapps
+some_project_name
+myproject
-standard django files
-settings.py
-app_directory
+apache2
+bin
-start
-stop
-restart
-other dirs
-bin
-lib
-myproject.wsgi
-some_project2
-symlink_to_static_files
If you are building your project under "myproject", you should not have to modify the wsgi file to get started- just change to the apache2/bin directory and run ./start and you're good to go!
If you change the wsgi file you'll need to run ./stop then ./start to activate the changes.
If the path you listed isn't working, it may be worth trying to create a generic django project and just puaste your project right over 'myproject'
It seems like your service provider has already given you some helpful instructions:
http://docs.webfaction.com/software/django/getting-started.html

Categories