Here's what I'm working with right now:
Ubuntu Trusty 14.04
Rails 4.2.6
Ruby 2.2.3
Passenger
Nginx
When I try to visit the IP I get this message:
Incomplete response received from application
When I look at nginx/error.log I see:
Missing `secret_token` and `secret_key_base` for 'production' environment, set these values in `config/secrets.yml`
On the server I did:
RAILS_ENV=production bundle exec rake secret
I placed that result into each of these files for good measure:
~/.bashrc
~/.bash_profile
~/.profile
/app/shared/config/local_env.yml
For all shell scripts the format is:
export SECRET_KEY_BASE="[key]"
For the local_env.yml I used just:
SECRET_KEY_BASE="[key]"
I've also tried entering it without quotation marks.
I've restarted the server each time I made a change. No cigar.
What else might be the issue?
-- UPDATE
I've even added the secret key to the secrets.yml file directly. So now I'm thinking my issue is either something to do with passenger/nginx or with a typo somewhere.
It is more likely that the environment variables are not actually set rather than Rails is not picking them up. You're raking secrets, which I don't do. I set them up manually in the Unix etc/environment, and do not check any secrets into source control. But the following are a few steps that should help you either resolve or hone in on the problem.
On your Ubuntu server for system wide environment variables
1- $env
Look for your SECRET_TOKEN and SECRET_KEY_BASE. The error tells you that these are not set, this is just a technique to check env. (RAILS_ENV will also be shown in the list if it is set.)
2- $sudo nano /etc/environment
Add the following lines -- use your actual values between double quotes. Do not use a [key] or any programmatic replacement.
export SECRET_TOKEN="T99ABC..."
export SECRET_KEY_BASE="99ABC..."
3- $logout / $login to reload environment vars
4- $env - Check the environment again
Look for your SECRET_TOKEN and SECRET_KEY_BASE to be set.
5- Try deploying again. If it fails, check the environment vars using $env again. It will tell you if something in your deploy is smashing your SECRET_* env vars.
Related
When working with a ColdFusion server you can access the CFIDE/administrator to set config values, which update the cfusion/lib/ xml files (e.g. neo-runtime.xml, neo-mail.xml, etc.)
I'd like to automate a deployment process that includes setting these administrator values so that I don't have to log in and manually set them for each new box that shares settings. I'm unsure of the best way to go about it.
Some thoughts I had are:
Replacing the full files with ones containing my custom settings. I've done this for local development, but it may not be an ideal method due to CF hot-fixes potentially adding/removing/changing attributes.
A script to read the wddx xml file and replace the attribute values. I'm having trouble finding information about how to do this method.
Has anyone done anything like this before? Or does anyone have any recommendations on how to best go about this?
At one company, we checked all the neo-*.xml files into source control, with a set for each environment Devs only had access to the dev settings and we could deploy a local development environment with all the correct settings for new employees quickly.
but it may not be an ideal method due to CF hot-fixes potentially adding/removing/changing attributes.
You have to keep up with those changes and migrate each environment appropriately.
While I was there, we upgraded from 8 to 9, 9 to 11 and from 11 to 2016. Environments would have to be mixed as it took time to verify the applications worked with each new version of CF. Each server got their correct XML files for that environment and scripts would copy updates as needed. We had something like 55 servers in production running 8 instances each, so this scaled well.
There is a very usefull tool developed by Ortus Solutions for this kind of automatizations called cfconfig that can be installed with their commandbox command line utility. This tool isn't only capable of setting configurations of the administrator: It is also capable of exporting/importing settings to a json file (cfconfig.json). It might be what you need.
Here is the link to their docs
https://cfconfig.ortusbooks.com/introduction/getting-started-guide
CFConfig worked perfectly for my needs. I marked #AndreasRu answer as accepted for introducing me to that tool! I'm just adding this response with some additional detail for posterity.
Install CommandBox as part of deployment script
Install CFConfig as part of deployment script
Use CFConfig to export a config.json file from an existing box that will share settings with the new deployment. Store this json file in source control for each type/env of box.
Use CFConfig to import the config.json as part of deployment script
Here's a simple example of what this looks like on debian
# Installs CommandBox
curl -fsSl https://downloads.ortussolutions.com/debs/gpg | apt-key add -
echo "deb https://downloads.ortussolutions.com/debs/noarch /" | tee -a /etc/apt/sources.list.d/commandbox.list
apt-get update && apt-get install apt-transport-https commandbox
# Installs CFConfig module
box install commandbox-cfconfig
# Import config settings
box cfconfig import from=/<path-to-config>/config.json to=/opt/ColdFusion/cfusion/ toFormat=adobe#11.0.19
I am trying to set Environment Variables for a Nginx And Gunicorn Served Django Project on Ubuntu.
The variables are set for the Ubuntu user and i am able to see the value using printenv VAR_EMAIL.
But when i use them django settings it is not working , using them as os.environ['VAR_EMAIL'],This doesn't get the value of the variable in production and server doesn't work.
However this works on Development side.
UPDATE 1st May 2020:
I used systemd and passed the variable like this in gunicorn.service file.This won't work still get key error,)Will post the exact error) as it is production on Ubuntu but i am developing on Windows and it works fine with Environment Variables in Development.
is os.environ['var_name'] correct way to access that ?
I also tried os.environ.get('var_name') as i saw in some video that environ have .get() to access the value. I will try again maybe i made some mistake.Feel free to ask for any info required.
ANSWERED - It was error on my end.
What are you using to supervise and run the gunicorn process in Ubuntu? If you're not using any, I recommend you to use systemd, there's a small guide on how to setup in the gunicorn docs: https://docs.gunicorn.org/en/stable/deploy.html#systemd
After that, you can set the environment variables in the systemd config file doing like the following, under the [Service] section of the systemd config file:
[Service]
Environment="VAR_EMAIL=var-email"
Environment="ANOTHER_VAR=another-var"
You can also use the EnvironmentFile directive if you prefer to have these variables in a separate file: https://www.freedesktop.org/software/systemd/man/systemd.exec.html#EnvironmentFile=
Now after many problems i faced because of which i just hard coded the
variables in code for long time the solution i reached is in this
update.Read the complete answer to get it.
This is an update,it is odd how the environment variables are passed along.
Every variable require the following method but you also need to add the variables to the etc/environment and add the Environment variables in it too.
The environment Variables were to be set in a single line with spaces separating each key+value pair. (Not like mentioned in selected Answer)
Couldn't get it to work with supervisor though.
So the correct way to do it is as mentioned in this Documentation for Systemd : EnvironmentsSystemd
Environment = "KEY_NAME_1=VALUE_KEY_1" "KEY_NAME_2=VALUE_KEY_2" ....
Then User PassEnvironment to activate those in that session.
This way with PassEnvironment you can have different Environment Variables active for Different Services.
PassEnvironment = KEY_NAME_1 KEY_NAME_2 ....
This is Key Names seperated by spaces.
This should help you setup systemd . Check the Selected answer for all the links.
This won't work:
I'm using Anaconda 2.7 on windows, and my internet connection uses a proxy.
Previously, when using python 2.7 (Not Anaconda), I installed package like this:
pip install {packagename} --proxy proxy-us.bla.com:123
Is there a way to run conda with proxy argument? didn't see it in conda help.
Thanks
Or you can use the command line below from version 4.4.x.
conda config --set proxy_servers.http http://id:pw#address:port
conda config --set proxy_servers.https https://id:pw#address:port
You can configure a proxy with conda by adding it to the .condarc, like
proxy_servers:
http: http://user:pass#corp.com:8080
https: https://user:pass#corp.com:8080
or set the HTTP_PROXY and HTTPS_PROXY environment variables. Note that in your case you need to add the scheme to the proxy url, like https://proxy-us.bla.com:123.
See http://conda.pydata.org/docs/config.html#configure-conda-for-use-behind-a-proxy-server.
One mistake I was making was saving the file as a.condarc or b.condarc.
Save it only as .condarc and paste the following code in the file and save the file in your home directory. Make necessary changes to hostname, user etc.
channels:
- defaults
show_channel_urls: True
allow_other_channels: True
proxy_servers:
http: http://user:pass#hostname:port
https: http://user:pass#hostname:port
ssl_verify: False
The best way I settled with is to set proxy environment variables right before using conda or pip install/update commands. Simply run:
set HTTP_PROXY=http://username:password#proxy_url:port
For example, your actual command could be like
set HTTP_PROXY=http://yourname:your_password#proxy.your_company.com:8080
If your company uses https proxy, then also
set HTTPS_PROXY=https://username:password#proxy_url:port
Once you exit Anaconda prompt then this setting is gone, so your username/password won't be saved after the session.
I didn't choose other methods mentioned in Anaconda documentation or some other sources, because they all require hardcoding of username/password into
Windows environment variables (also this requires restart of Anaconda prompt for the first time)
Conda .condarc or .netrc configuration files (also this won't work for PIP)
A batch/script file loaded while starting Anaconda prompt (also this might require configuring the path)
All of these are unsafe and will require constant update later. And if you forget where to update? More troubleshooting will come your way...
I was able to get it working without putting in the username and password:
conda config --set proxy_servers.https https://address:port
You can configure a proxy with conda by adding it to the .condarc, like
proxy_servers:
http: http://user:pass#corp.com:8080
https: https://user:pass#corp.com:8080
Then in cmd Anaconda Power Prompt (base) PS C:\Users\user> run:
conda update -n root conda
On Mac what worked for me was going to keychain and updating the password for the key that for the company's the internal repo.
I am having a difficult time setting up Rails 4.2 in production on a VM running on passenger and nginx, and not using RVM or anything similar.
I got Incomplete response received from application and looking in the nginx error log it said something about missing secret_key_base and secret_key although there is no reference to that last one any where in the config directory.
I ran export SECRET_KEY_BASE='...' and in rails c production ENV["SECRET_KEY_BASE"] displays the key but after restarting nginx I still get the same error.
Placing the key directly in secrets solved that problem but is there an actual way to do this correctly?
Solution:
The solution that worked for me is to place export SECRET_KEY_BASE="<string obtained from rake secret>" in .bashrc
If you use rbenv, there is another solution below in the accepted answer.
If you are using rbenv you can add the rbenv-vars plugin and add a .rbenv-vars file containing (and don't check that into your repo)
SECRET_KEY_BASE='...'
other solution is to add the the SECRET_KEY_BASE manually to the secrets.yml file and also ignore that file from your repo.
a third answer that saw mentioned is adding
export SECRET_KEY_BASE='...'
to one of these files .bashrc .bash_profile .profile
Your config/secrets.yml should have something like
development:
secret_key_base: f91fe2e2e4a9bf8f8b6aa1c296bb9ec10f2bc91c08965176a642ea0927400651ea993512f83d9823bcc046555e40b8c257f5f19fab8c59b5a02c9d230a369fe7
test:
secret_key_base: c116ac7c8f69018d1f4e10f632cac7a22348f0bd8ed8f21ca45460574d2f501f248418bc888e31556e16ba3ab58c3a7cba027140097abe3f511dddf6625fa8cd
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
To set SECRET_KEY_BASE, first you'll need to generate it with
rake secret
Then take that output and edit your /etc/environment (depending on your distro, assuming Ubuntu here) and place it as such
SECRET_KEY_BASE=...
Restart your server and you should be gravy
I'm working on a number of projects on cloud9 IDE, and it's really frustrating that I can't get the better errors gem to work correctly. It isn't supposed to need initializing; it should just work out of the box. However, I still only get the usual ugly red errors page. I should specify that it is included in my gemfile, and I have bundle install already.
How can I get better errors to work correctly? Is there an installation step I'm missing?
The trick, I used, to get the 'better_errors' gem working in Cloud9 is setting the value of TRUSTED_IP to the public IP address of the computer my browser session is attached to. (As far as I can tell, it has nothing to do with the IP address of the remote server or Cloud9 server addresses.)
I'll outline the process I used to get 'better_errors' working on my Cloud9 workspace, from my Chromebook on my residential network... maybe it will also work for you and others!
Add gem "better_errors" to the development group in the project Gemfile.
Add gem "binding_of_caller" to the project Gemfile.
Run $bundle in the project Cloud9 terminal.
Edit the project config/environments/development.rb file and add the following line of code to the end of the Rails.application.configure block.
BetterErrors::Middleware.allow_ip! ENV['TRUSTED_IP'] if ENV['TRUSTED_IP']
Create a new "runner" in Cloud9 by clicking "Run" > "Run With" > "New Runner".
Cloud9 creates an basic runner file in a new tab to modify. Replace the contents of this file with following code.
{
"cmd": [
"bash",
"--login",
"-c",
"TRUSTED_IP=XXX.XXX.XXX.XXX rails server -p $port -b $ip $args"
],
"working_dir": "$project_path",
"info": "Your code is running at \\033[01;34m$url\\033[00m.\n\\033[01;31m",
"selector": "source.ru"
}
Replace XXX.XXX.XXX.XXX in the code above with the local computer's public IP address. (I use http://ifconfig.me/ to find the public IP assigned to my Chromebook.)
Save the runner file with the name RoR.run into the /.c9/runners path for the project.
Start the projects server by using this new runner. Click Run > Run With > RoR.
Use the popup link that Cloud9 displays, after the runner starts the server, to view the app. Enjoy 'better_errors'!
NOTE: I still have not figured out how to automate the process of feeding the external IP address of my local computer into the RoR.run file that lives on the Cloud9 workspace. I just update it manually every time I move to a new network or my external IP address changes.
WARNING: I actually just started learning RoR, so I have no idea if this is the "correct" way to get this gem to work in a cloud dev server/service environment. I also have no idea how safe this would be. I suspect that my solution exposes the 'better_errors' in-browser REPL to all computers that resolve to that same external IP address. If you are working on a sensitive codebase/database please do not implement my solution.
I just tested this in cloud9.io and this is the simplest way to make this work in cloud9.io:
Add the following line to config/environments/development.rb:
BetterErrors::Middleware.allow_ip! 'xxx.xxx.xxx.0/24'
where xxx.xxx.xxx is the first three sections of the IP address of the local machine that you are using to connect to cloud9.io
There is a good answer in the better errors issues and c0 docs.
Issues:
https://github.com/charliesome/better_errors/issues/318
c9 Help
https://community.c9.io/t/white-listing-remote-addr-for-better-errors-gem/4976/4
Use a Rack::Request object to get the IP. You can put the following code in your view.
if Rails.env.development?
request = Rack::Request.new(env)
puts "###### Request IP_ADDRESS = #{request.ip}"
end
Change the last quadrant of the IP you get to 0/24. For example.
BetterErrors::Middleware.allow_ip! '76.168.69.0/24' <--note: change the last quad to 0/24 and of course your ip address will be different than 76.168.69.xx
Yeah!! I got it! Automatically!
Here is my solution:
1- Similar as described by #Grokcodile: edit the project config/environments/development.rb file and add the following line of code to the Rails.application.configure block.
BetterErrors::Middleware.allow_ip! ENV['TRUSTED_IP'] if ENV['TRUSTED_IP']
config.web_console.whitelisted_ips = ENV['TRUSTED_IP']
2- At the Cloud9 edit the ~/.bashrc...
vi ~/.bashrc
add the line (enter, alt+a):
export TRUSTED_IP='0.0.0.0/0.0.0.0'
Save it (esc, :wq)
3- run rails s -b $IP -p $PORT as usual...
4- Enjoy better errors!!
If you also work on this project at a Virtual Machine(vagrant):
1- edit at your VM (vagrant) your ~/.bash_profile (my case) and add:
export TRUSTED_IP=x.x.x.x
export PORT=3000
export IP=0.0.0.0
x.x.x.x must be equal to the REMOTE_ADDR of ENV. (This in not a problem like cloud9 because at my VM the IP doesn't change everytime: 10.0.2.2 always for me).
With this I am now able to use the gem foreman: foreman start at both places with the Procfile:
web: rails s -b $IP -p $PORT
This works because the global env variables are set on both.
I am just starting to learn RoR too, so, hope this is the right thing to do without bringing more problems in the future.
Because Cloud9 is all web-based you don't access it from localhost so by default better errors won't work. If you take a look at the security section of their README (https://github.com/charliesome/better_errors) you can add the following to config/environments/development.rb:
BetterErrors::Middleware.allow_ip! <ipaddress>
So that the errors page shows for your IP. You can find your apparent IP by hitting the old error page's "Show env dump" and looking at "REMOTE_ADDR".