What should be removed from public source control in Ruby on Rails?

前端 未结 2 1771
粉色の甜心
粉色の甜心 2020-12-23 12:16

I\'ve been searching the web, and I can\'t find any good/recent examples of what to exclude from a new public rails app. I\'m looking to open source my app on GitHub and am

相关标签:
2条回答
  • 2020-12-23 12:44

    I've been looking into this recently as well; I wanted to keep sensitive information hidden throughout the process of pushing open source code to Github, then automatically pushed to Travis CI for testing, then from Travis being automatically deployed to Heroku. Here are all the details of what I've found so far looking at various StackOverflow Q&As, blogs etc, which will hopefully serve as a reference for you, even if only for config inside the Rails app (omit any {{ ... }} you see)

    Disclaimer: I'm by no means an expert here, so please keep in mind there are likely better ways to do this than what I'm trying. I'd love to be able to learn some new tricks in this Q&A thread.


    Inside the Rails App

    I currently use the Figaro gem to hide sensitive information in ENV environment variables. In my (.gitignored) config/application.yml, I keep the following information:

    # App keys
    SECRET_TOKEN: # your rake secret generated token
    
    development:
      DB_NAME: # your dev db name here
      DB_USER: # your dev db username here
      DB_PASSWORD: # your dev db password here
    
    test:
      DB_NAME: # your test db name here
      DB_USER: # your test db username here
      DB_PASSWORD: # your test db password here
    
    production:
      DB_NAME: # your prod db name here
      DB_USER: # your prod db username here
      DB_PASSWORD: # your prod db password here
    
    # Third Party keys that you will reference in their relevant files
    THIRD_PARTY_API_OR_LICENSE_KEY: # list of whatever api/license keys you use
    

    (DB_NAME, DB_USER, and DB_PASSWORD will be used dynamically depending on what environment your app is running in).

    An empty version of the above file (config/application.example.yml) gets pushed to Github with some instructions on how to fill it in.

    The files that are pushed to Github and reference these variables look like this:

    config/database.yml
    (Postgresql is used here, but you should be able to change the settings for whatever database you use)

    postgresql: &postgresql
      adapter: postgresql
      database: <%= ENV['DB_NAME'] %>
      username: <%= ENV['DB_USER'] %>
      password: <%= ENV['DB_PASSWORD'] %>
      min_messages: ERROR
    
    defaults: &defaults
      pool: 5
      timeout: 5000
      host: localhost
      <<: *<%= ENV['DB'] || "postgresql" %>
    
    development:
      <<: *defaults
    
    test:
      <<: *defaults
    
    production:
      <<: *defaults
    

    config/initializers/secret_token.rb

    if Rails.env.production? && ENV['SECRET_TOKEN'].blank?
      raise 'SECRET_TOKEN environment variable must be set!'
    end
    
    YourApp::Application.config.secret_token = 
      ENV['SECRET_TOKEN'] || {{WHATEVER_SECRET_TOKEN_RAILS_GENERATED_BY_DEFAULT}}
    

    (Plus, whatever files would be referencing THIRD_PARTY_API_OR_LICENSE_KEY-type keys.)

    Testing on Travis CI

    Create encrypted travis variables using the Travis gem. The Heroku API key and Heroku Git URL are needed if you deploy direct to Heroku from a Travis worker (see this StackOverflow Q&A for details), otherwise you can omit them if you just use it for testing:

    $ gem install travis
    $ travis encrypt your_username/your_repo HEROKU_API_KEY={{YOUR_HEROKU_API_KEY}}
    $ travis encrypt HEROKU_GIT_URL={{YOUR_HEROKU_GIT_URL}} # eg git@heroku.com:your_app.git
    $ travis encrypt DB_NAME={{YOUR_DB_NAME_UNDER_TEST}} # eg your_app_test
    $ travis encrypt DB_USER={{YOUR_DB_USER_UNDER_TEST}}
    $ travis encrypt DB_PASSWORD={{YOUR_DB_PASSWORD_UNDER_TEST}}
    

    (Plus, encrypt any other keys you may need during testing, if any...)

    Then add them to .travis.yml
    (once again Postgresql-focused, but you should be able to change the settings for whatever database you use)

    env:
      global:
        - secure: {{YOUR_ENCRYPTED_HEROKU_API_KEY}}
        - secure: {{YOUR_ENCRYPTED_HEROKU_GIT_URL}}
        - secure: {{YOUR_ENCRYPTED_DB_NAME}}
        - secure: {{YOUR_ENCRYPTED_DB_USER}}
        - secure: {{YOUR_ENCRYPTED_DB_PASSWORD}}
      matrix:
        - DB: postgresql
    before_script:
      - psql -c "create database $DB_NAME;" -U $DB_USER
      - RAILS_ENV=test bundle exec rake db:migrate
    script:
      - bundle exec rspec spec/
    after_success:
      - gem install heroku
      - git remote add heroku $HEROKU_GIT_URL
      # ... see link above for the rest of the config content
    

    Multiple variables marked with the same name of secure are fine; they'll show up in the config as HEROKU_API_KEY=[secure] HEROKU_GIT_URL=[secure] etc.

    Deployment to Heroku

    Use the Figaro's Heroku rake task to automatically set the environment variables that Heroku needs to see in production:

    $ rake figaro:heroku
    

    Or, set them manually:

    $ heroku config:set SECRET_TOKEN={{YOUR_SECRET_TOKEN}}
    $ heroku config:set DB_NAME={{YOUR_DB_NAME_UNDER_PRODUCTION}} # eg your_app_production
    $ heroku config:set DB_USER={{YOUR_DB_USER_UNDER_PRODUCTION}}
    $ heroku config:set DB_PASSWORD={{YOUR_DB_PASSWORD_UNDER_PRODUCTION}}
    $ heroku config:set THIRD_PARTY_API_OR_LICENSE_KEY={{YOUR_THIRD_PARTY_API_OR_LICENSE_KEY}}
    

    Then, attempt a deployment.


    That's all I have for now. Not sure at the moment if I should be hiding more info or if I'm not hiding it well enough, but it's a work in progress.

    0 讨论(0)
  • 2020-12-23 13:00

    You'll get different opinions. IMHO, it's best-practice to include these files, but omit the secret content from them. Document what you're doing so developers who are new to your project know what they need to fill in.

    Phusion has a good blog post about how to handle the Rails session secret, and the tradeoffs you can make to include or exclude information:

    http://blog.phusion.nl/2013/01/04/securing-the-rails-session-secret/#.URYPXekTMak

    My favorite way to document these is using a "rake setup" task. You can have the task print what the developer needs to do-- in other words, you don't need to automate it all (though that's nice if you're able to do it).

    If you want to get fancy, have your files read the secret settings from a shared/ directory, which also enables deployment symlinking. This is described in the Phusion blog too. This is how I build apps that need to be deployed frequently.

    0 讨论(0)
提交回复
热议问题