I'm trying to deploy Ghost 1.2.0 to Heroku. With previous versions of Ghost (<= 0.11.x), they used a config.js file where you could just do:
database: {
client: 'postgres',
connection: {
host: process.env.POSTGRES_HOST,
user: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD,
database: process.env.POSTGRES_DATABASE,
port: process.env.POSTGRES_PORT
},
debug: false
}, …
But in this version they're using nconf that replaces this config.js for environment dependent JSON files like config.production.json.
JSON files unlike JS objects can't have vars as values. I could hardcode my credentials to the JSON file, but I don't want to do that because:
Looks like a bad practise to me, and
Heroku rotates credentials periodically and updates applications where this database is attached. (Quoted from Heroku)
After some digging into nconf README and issues I understood that it would be possible to imitate this expected database object just with:
nconf.env({
separator: '__' // Two dashes
});
and defining vars as:
heroku config:set DATABASE__CLIENT=postgres
heroku config:set DATABASE__CONNECTION__HOST=<value>
...
but, no matter what, I get undefined when I later call:
nconf.get('database');
nconf.get('DATABASE'); // In case it was case-sensitive...
Instead, if I call:
nconf.get('DATABASE__CLIENT'); // postgres
it works. I could try (and I will) to modify Ghost scripts to read all variables this way, but as long as it expects a database object it'll be so cool to get it working the right way.
So, has anybody figured out how to correctly recreate an object with Heroku's env vars?
I've finally found the solution.
Unless you want to modify nconf.env(settings) like:
nconf.env({
separator: '__', // Two dashes
lowerCase: true
});
This will make it possible to pass lowerCase: true to env() so that if an environment variable is called SOMETHING or SOMEthing, it will also be gettable using something [Source]
I recommend to use already lowercase env vars.
So,
heroku config:set database__client=postgres
will be readable using:
nconf.get('database:client');
Looks like nconf has a different character separator to define nested variables called separator and another one to read them called logicalSeparator (its default value is :)
Related
I'm new to Go and Buffalo, and am attempting use my bash environment variables in my database.yaml
I attempted to do the following in my database.yaml, but it fails to interpret the value of my bash environment var localUser
user: ${localUser}
I set the localUser with the following bash
export localUser="username"
echo $localUser
username
Thanks for any help!!
Buffalo Pop's configuration, database.yml, supports the following syntax.
production:
host: "localhost"
user: {{ envOr "localUser" "defaultuser" }}
test:
dialect: "mysql"
url: {{ envOr "TEST_DATABASE_URL" "mysql://user:pass#(localhost:3306)/test" }}
The key is the envOr directive.
As you can imagine, the production.user will be set as the value from the environment variable localUser if the value exists, but it will fall back to its default value "defaultuser" if there is no environment variable.
With this syntax, you can configure environment-specific values dynamically.
This is good for many situations such as container images that could be used in multiple different configurations. You can distribute (or publish) your application "image" with the default value, then you can run your "container" with specific environmental variables with the real values.
I am using the dotenv Gem to read variables in my .env file. I created a console command that updates the .env file, but also in the same runtime, it reads them. The problem is that it reads the old values, even though I updated the .env file. Is there a way to refresh the ENV during runtime so it gets the latest values?
.env
FOOBAR=hello
ruby.rb
puts ENV['FOOBAR'] # Prints "hello"
EnvFile.update_variable('.env', 'FOOBAR', "How are you?")
Dotenv.load('.env')
puts ENV['FOOBAR'] # Prints "hello" even though looking in .env it has the new value "How are you?"
Do you mean you are using dotenv? rbenv manages ruby installs and doesn't read .env from what I searched in the source code. With dotenv, you can reload ENV from the .env file by calling Dotenv.load. It's probably going to give you warnings about constants being redefined. What I would do is make a config class to combine the default settings from ENV with the redefining feature/function you want. Config manages everything but reads defaults from .env.
You can refresh with the following:
Dotenv.overload('.env')
Thank you domcermak for answering this at: https://github.com/bkeepers/dotenv/issues/426
I have a .properties files as below:
user:abcd
pwd:xyz
system:test
Next, I have a ruby script with Watir for browser automation. In this script, I have statements like
browser.text_field(:id => 'identifierId').set "#{user}:variable to be replaced by its value from .properties file".
Similarly, other values need to be replaced for "pwd" and "system".
I tried the solution per below posts:
Replace properties in one file from those in another in Ruby
However, "set" command is setting whatever has been paased as arguments to it instead of replacing the variable with its value.
Please help.
You have to read the information out of the file.
Most Watir users leverage yaml files for this.
config/properties.yml:
user: abcd
pwd: xyz
system: test
Then read the yaml file & parse your data:
properties = YAML.safe_load(IO.read('config/properties.yml'))
text_field = browser.text_field(id: 'identifierId')
text_field.set properties['user']
Alternately you can take a look at Cheezy's Fig Newton gem, which is designed to work with his Page Object gem
I'm trying to configure a properties file in a puppet module. The properties file should end up with content like this:
server_url=https://my-login.com/server
token_url=https://my-login.com/token
client_id=my-application
We have multiple environments that the application will be deployed to (development, staging and production), the server_url and token_url will be different in each environment, but the client_id will always be the same. So I made an erb template like this:
server_url=<%=#server_url%>
token_url=<%=#token_url%>
client_id=my-application
And a manifest file like this:
# $env will be DEV, STG or PRD
$server_url = 'https://my-login-dev.com/server'
$token_url = 'https://my-login-dev.com/token'
file {'/apps/my-application/common/client.properties':
ensure => 'present',
content => template("common/client.properties.erb"),
}
I want the values of the server_url and token_url to be set based on the value of the env variable. Ideally this would work by choosing a particular file to include. For example, have an urls.properties file for each environment, which the variables get loaded from. So urls.properties.dev would contain something like:
server_url=https://my-login.com/server
token_url=https://my-login.com/token
And then you could just include it like so:
# server_url and token_url set up by the following line
include urls.properties.${env}
file {'/apps/my-application/common/client.properties':
ensure => 'present',
content => template("common/client.properties.erb"),
}
I can't find any documentation on how to do this, and I can't find a way to make it work by hacking around.
Is it possible to achieve this? Is there another approach I should be taking to solve the problem? (I don't want to use partial templates, as I don't want the file to be split into lots of chunks).
Revel uses app.conf for storing configuration. I want my configuration to get value from environment variable using os.Getenv(key)
How can I do it? Should I use revel.Config to make changes? if so where do I place it?
Or is there another way?
I use it mainly for storing database information (I don't want to enter my credential in configuration files)
Thank you
Revel uses revel/config for managing app.conf.
And the only place revel/config foes read from the environment variable is in type.go (c *Config) String() method.
// $ environment variables
computedVal, _ = c.computeVar(&value, envVarRegExp, 2, 1, func(varName *string) string {
return os.Getenv(*varName)
})
That means you could add in a config file values based on the name of environment variable, which would allow you to use said environment variable to modify the config.
See an example in the revel/config REAMD.md file.
[DEFAULT]
host: www.example.com
protocol: http://
base-url: %(protocol)s%(host)s <====
The OP pveyes points out to this comment in type.go:
// substitute by new value and take off leading '%(' and trailing ')s'
// %(foo)s => headsz=2, tailsz=2
// ${foo} => headsz=2, tailsz=1
So:
when using environment variables use ${ENV_VARS}, and
for unfolding variables use %(UNF_VARS)s