Rails: use another .env file - ruby-on-rails

I am running a mastodon server with two instances on the same server.
Mastodon is basically a rails app and has the command line tool called tootctl.
Normally you use it like so:
RAILS_ENV=production bin/tootctl accounts modify alice --role Owner
This uses the default env file .env.production that was created when installing the first instance.
But now I need to manage the second instance for which I need to use the second env file .env.production.de
Question: How do I tell rails to use another .env file than the default one?
I would need something like
RAILS_ENV=production RAILS_ENV_FILE=.env.production.de bin/tootctl accounts modify alice --role Owner .

For each of the Rails apps you can use Option Three: Use a local_env.yml File as found in this article: http://railsapps.github.io/rails-environment-variables.html
So something like:
The local_env.yml File
Create a file config/local_env.yml:
# Rename this file to local_env.yml
# Add account settings and API keys here.
# This file should be listed in .gitignore to keep your settings secret!
# Each entry gets set as a local environment variable.
# This file overrides ENV variables in the Unix shell.
# For example, setting:
# GMAIL_USERNAME: 'Your_Gmail_Username'
# makes 'Your_Gmail_Username' available as ENV["GMAIL_USERNAME"]
GMAIL_USERNAME: 'Your_Gmail_Username'
Set .gitignore
If you have created a git repository for your application, your application root directory should contain a file named .gitignore (it is a hidden file). Be sure your .gitignore file contains:
/config/local_env.yml
This prevents the config/local_env.yml file from being checked into a git repository and made available for others to see.
Rails Application Configuration File
Rails provides the config/application.rb file for specifying settings for various Rails components. We want to set our environment variables before any other settings. Rails provides a config.before_configuration method to do so.
Find the following code at the end of the config/application.rb file:
#Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
and add this code after it:
config.before_configuration do
env_file = File.join(Rails.root, 'config', 'local_env.yml')
YAML.load(File.open(env_file)).each do |key, value|
ENV[key.to_s] = value
end if File.exists?(env_file)
end
The code opens the config/local_env.yml file, reads each key/value pair, and sets environment variables.
The code only runs if the file exists. If the file exists, the code overrides ENV variables set in the Unix shell.
This way each Rails app has its own ENV variables but you can access them all with the same ENV["SOME_KEY"]
Important: Understand that since these files are in .ignore they won't get backed up to version control. But also if you are pushing to your production sever elsewhere they won't get copied over, you'd have to do that manually. And if you are storing passwords or API keys the file is not encrypted in any way so it is not secure if someone gains access to your server. I'm not sure how services like Heroku store their ENV variables that you can set. Probably encrypted in your Rails install using your profile. You will probably want to research that if you choose to go this route.

Related

Where should I put keys at my rails app?

I am trying to use the gem webpush to create push notifications at my rails app.
At this part at tutorial he say:
"Use webpush to generate a VAPID key that has both a public_key and private_key attribute to be saved on the server side."
# One-time, on the server
vapid_key = Webpush.generate_key
# Save these in your application server settings
vapid_key.public_key
vapid_key.private_key
My doubt is: What exactly is "application server settings"? Where should I put these keys at my rails app?
Idealy it should be stored in environment variables (depends on the OS you use).
If you are using dotenv gem and find it conveniant to use dotenv in production you can store it in .env file.
To use a variable use ENV['NAME']
Also for this purpose you can use default rails config/secrets.yml file. To use a variable use Rails.application.secrets.name.
Also you can combine env variables with secrets.yml file like:
secrets.yml
...
key: ENV['NAME']
benefit: use variable independent of rails environment.
Notice: Neve share you credentials file to git or any public repo! If you need to share this file with other developers just send them copy with development keys.
Links:
dotenv
environment variables
secrets.yml
I wrote a gem to help with this now that Rails no longer supports secrets.yml.
REMINDER: you should never store a private key or any other secret variable in a file that is committed to your version control - use environment variables for that.

Where do I put the Google API .json key file?

I am trying to integrate Google Calendar API into my Rails app, so I can create Google calendar events from my app.
Google has provided a client_secret.json file. I can use it locally, but now have no idea how to implement the key file on heroku.
Can anyone help me with this?
It should just be a secret and key (the names and values).
For heroku, you can set them as environment variables. Like so:
heroku config:set GOOGLE_SECRET=8N029N81ASLDKFA823_WO4ANF
(but please use the information provided in your json file)
Now. The next step is to make sure that your application only calls for those keys in a single way. An option is to use the config/secrets.yml file. Call to the environment variable in the secrets file. Then, you can use the dotenv gem in development so you have .env file in your application's root where you place all your env vars (but do NOT check in the .env file)
Create a file if it doesn't exist config/secrets.yml and inside it add:
production:
google_secret: ENV['GOOGLE_SECRET']
development:
google_secret: ENV['GOOGLE_SECRET']
(obviously, again, make sure the name is what you choose)
Next add dotenv to your gem file and run bundle
gem 'dotenv-rails', :groups => [:development, :test]
Create a new file called .env in the app's root. And add your variable directly including both the key name and the value.
GOOGLE_SECRET=8N029N81ASLDKFA823_WO4ANF
You can add as many env variables as you need to.
Now edit the .gitignore file and add the .env file to it, to make sure you don't accidentally check in your private information.
Lastly, in any place that you need to USE the environment variable, is to call it from secrets like so:
Rails.application.secrets.google_secret
I know it seems like a lot of steps, but it will ensure that you dev matches your prod without making a lot of if Rails.env.development? statements in your code.

Where is SECRET_KEY_BASE environment variable located when I start Rails app in Production

In the Rails 4 In Action Book, it states that after doing some other setup: the final setup to boot up your rails app in production mode (with web brick) is to enter this command in terminal:
SECRET_KEY_BASE='rake secret' rails s -e production
I am trying to see where the environment variable of SECRET_KEY_BASE is stored.
Within /app/config/secrets.yml it says that the secret_key_base variable is an environment variable:
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
But I looked within .bashrc and .bash_profile and the variable SECRET_KEY_BASE is not there.
Ultimately I want to know: where is environment variable and its value? Is it stored somewhere in my rails app? I hope not for security purposes if I push this app to github. I assume it is not stored in the app but in my computer system somewhere. Within a different terminal window I do echo $SECRET_KEY_BASE but nothing gets returned.
Thanks in advance for helping me understand the missing pieces.
As a side note: I am aware of this question, but the question is not as detailed and there is no provided answer.
When you run this:
SECRET_KEY_BASE='rake secret' rails s -e production
you are not actually 'saving' the secret key for future you. You're defining it on a one-time basis. Whenever you run a Ruby command you can set temporary environment variables:
# from shell
KEY="VAL" OTHER_KEY=OTHER_VAL ruby my_command.rb
# from the ruby script
puts ENV["KEY"] # => "VAL"
puts ENV["OTHER_KEY"] # => "OTHER_VAL"
To persist the environment variables you have a couple options. You could hard code them in your source code, but this is probably not a good idea because if you push your code to Github, anyone will be able to see it. That's kind of the point of environment variables, anyway, that you can keep them system specific.
Option A
You can set them in .bashrc or .bash_profile
First get the result of rake secret (will be a random string) and set a shell variable:
KEY=`rake secret` # uses backticks to get command result
Then add a line in bashrc to export it:
echo -e "export SECRET_KEY_BASE=$KEY" >> ~/.bashrc
Option B
This is the one I'd recommend, you can use dotenv or figaro to manage your environment variables in an app-specific way, i.e. without cluttering up your bashrc.
For example with dotenv you'd create a .env file which contains:
# change this to the result of rake secret
SECRET_KEY_BASE=j3e2dd293d
This would be excluded from source control by adding it to gitignore.
Then in your ruby app you call
require 'dotenv'
Dotenv.load
and your ENV["SECRET_KEY_BASE"] will be set.
If you want you can make a .env.example file (included in source control) which shows which environment variables need to be defined. Then when the app is cloned you can run mv .env.example .env and customize .env.

Different local database configuration Rails

I'm working in a team in a Rails project.
Each of us have a local database for development purpose. We have a problem: Everyone have different configuration for the local database. When someone make a commit without reset the /config/database.yml the other members of the team can't use their database because the access is not configured.
Can I have a local configuration not commited? To each one can works without problem and without the need of re-set the file every time? Sometime like the local_settings.py in Django
You can configure the database in Rails via both the config/database.yml file and the DATABASE_URL env var. They are merged but settings from DATABASE_URL take precedence.
A good solution is to check in the config/database.yml with a basic configuration thats just enough to support postgres.app or whatever is the most common solution.
Developers that need other settings can set the DATABASE_URL env var to customize the database configuration. Gems like figaro and dotenv make this easier.
If you have ever wondered this how Heroku manages to use the correct DB no matter what you throw into database.yml and the DATABASE_URL ENV var is how you should be configuring your production DB.
Why should I use ENV vars and not more database_*.yaml files?
The twelve-factor app stores config in environment variables (often
shortened to env vars or env). Env vars are easy to change between
deploys without changing any code; unlike config files, there is
little chance of them being checked into the code repo accidentally;
and unlike custom config files, or other config mechanisms such as
Java System Properties, they are a language- and OS-agnostic standard.
https://12factor.net/config
Add config/database.yml in to the .gitignore file at root path of your rails-app.
Copy config/database.yml with the values you need for production into config/database_example.yml.
Now you can modify your local database and in production you copy config/database_expample.yml to config/database.yml
If the config file is ignored by git, everyone can change it locally without getting tracked by git.
EDIT:
HERE YOU SEE HOW YOU CAN REMOVE FILE FROM TRACKING!!!
Ignore files that have already been committed to a Git repository

How to set up and use Rails environment variables in production server?

I need to set up an environment variable for my rails app. Both in my local machine and in the production server. I read some tutorials on the internet but NONE has given the complete instruction on how to set and use these variable in the actual production server. I use digital ocean and linux server to host my rails app.
I have spent days trying to figure this out, but still haven't found a clear and complete instruction from setting the variables on my local machine -> push it to git repo -> set and use the variables in production server. So, hope somebody can help me here, thanks!
UPDATE:
This is how I currently setup the environment variables in my rails app by using figoro gem:
You can set system-wide environment variables in the /etc/rc.local file (which is executed when the system boots). If your Rails app is the sole user of the Linux system, that is a good place to store credentials such as API keys because there is no risk of including this file in a public Git repository, as it is outside the application directory. The secrets will only be vulnerable if the attacker gains shell access to your Linux server.
Set the environment variables within /etc/rc.local (do not include the <> characters):
export SOME_LOGIN=<username>
export SOME_PASS=<password>
To see the value of an environment variable, use one of the following commands in the Linux shell:
printenv MY_VAR
echo $MY_VAR
To access those environment variables within Rails, use the following syntax:
Inside .rb files or at the rails console
ENV['MY_VAR']
Inside .yml files:
<%= ENV['MY_VAR'] %>
For anyone still having this issue, figaro now has an easy method in setting the production variables in heroku. Just run:
$ figaro heroku:set -e production
ryzalyusoff.
For Unix
You can use LINUX ENV in rails application.
# .env
GITHUB_SECRET_KEY=SECRET
TWITTER_ACCESS_KEY=XXXXXXXXXXXX
# in rails code
puts ENV["TWITTER_ACCESS_KEY"] # => SECRET
Create .env files for local machine and your production server. Export environment variables like this(on server with ssh):
export GITHUB_SECRET_KEY="XXXXXXXXXXXXXXXXXX"
Anyway, storing keys in config - bad idea. Just add .env.example, others keys configs add to .gitignore. Goodluck.
Example with Rails
For Windows
Syntax
SET variable
SET variable=string
SET /A "variable=expression"
SET "variable="
SET /P variable=[promptString]
SET "
Key
variable : A new or existing environment variable name e.g. _num
string : A text string to assign to the variable.
expression : Arithmetic expression
Windows CMD
I believe we should not push a secret file on git.
To ignore such file use gitignore file and push other code on the git.
On the server side just copy the secret file and create a symlink for that file.
You can find demo here http://www.elabs.se/blog/57-handle-secret-credentials-in-ruby-on-rails
You can set your environment variables in production in the same way, you do it for local system. However, there are couple of gems, which make it easier to track and push to production. Have a look at figaro. This will help you in setting up and deployment of env vars.
You can do this with figaro gem
or in rails 4 there is a file named secret.yml in config folder where you can define your environment variables this file is by default in .gitignore file.For production you need to manually copy that file to server for security reason so that your sensitive information is not available to any one
First create your variable like:
MY_ENV_VAR="this is my var"
And then make it global:
export MY_ENV_VAR
You can check if the process succeeded with:
printenv
Or:
echo MY_ENV_VAR

Resources