Armazenar sua senha de banco de dados em database.yml é ruim por vários motivos. Vamos passar para o Rails por meio de uma variável de ambiente! (Usando Apache e Passenger.)
fundo
A maneira como o Heroku lida com várias chaves sensíveis, como a URL do banco de dados, é armazená-las em variáveis de ambiente. Você pode definir variáveis de ambiente na linha de comando usando a ferramenta de linha de comando heroku:
heroku config:add S3_KEY=<key_string>
Essa prática também é um dos Doze Fatores ( www.12factor.net/config ).
Ok, como você pode fazer isso funcionar se estiver hospedando seu aplicativo em seu próprio servidor?
database.yml
Basta substituir a string da senha por uma referência à variável de ambiente que iremos configurar:
<database.yml>
production:
...
password: <%= ENV['RAILS_DB_PWD'] %>
Lado do servidor
Tornar a variável de ambiente acessível ao seu aplicativo Rails é um pouco mais complicado. A solução irá variar dependendo da configuração do seu servidor, mas aqui assumirei que você está usando Apache + Phusion Passenger, mas o mesmo truque deve funcionar para a maioria das configurações com ajustes mínimos.
Você não pode simplesmente definir a variável de ambiente em um perfil de shell, porque isso não será carregado quando o Passenger for iniciado. Em vez disso, você cria um script de wrapper (ruby_wrapper) que é chamado quando o Passenger e define as variáveis lá.
Mas primeiro, vamos criar um script separado que realmente defina as variáveis (você verá o porquê em breve):
<set_environment>
export RAILS_DB_PWD=<password here>
Em seguida, criamos o wrapper e o set_environment de origem a partir dele:
<ruby_wrapper>
#!/bin/sh
source /path/to/set_environment
exec "/usr/local/bin/ruby" "$@"
(Certifique-se de que a última linha é a correta para o seu sistema. Execute “which ruby” se estiver em dúvida.) Eu gosto de manter este arquivo próximo à raiz do meu aplicativo Rails. O arquivo deve ser executável:
chmod +x ruby_wrapper
Agora você pode instruir o Passenger a usar este script de wrapper ao iniciar um processo Ruby, alterando uma linha em seu arquivo httpd.conf assim:
#PassengerRuby /usr/local/bin/ruby
PassengerRuby /path/to/ruby_wrapper
Acesso Shell (e Capistrano)
Neste ponto, se você tentar executar comandos rake em seu servidor por meio de um shell, eles falharão. Por quê? Porque você apenas disse ao Passenger para usar sua embalagem de rubi, mas não o resto do sistema. Precisamos exportar as mesmas variáveis para qualquer processo onde rake ou Rails serão executados. Isso é feito em um arquivo de inicialização do shell, geralmente (em sistemas Linux) em /etc/profile.d. Crie um novo script lá:
</etc/profile.d/my_profile.sh>
source /path/to/set_environment
Presto! Agora, os comandos rake funcionarão na linha de comando. Além disso, a execução de implantações do Capistrano e similares funcionará, porque os mesmos arquivos de inicialização serão carregados quando esses processos forem criados. (Definir o ambiente em ~ / .bash_profile não funcionaria nesses casos, no entanto.)
Agora você pode colocar qualquer coisa confidencial em seu arquivo set_environment, o que significa que você não precisa verificar em seu SCM (como git). Você também pode obter mais recursos e buscar suas variáveis de ambiente de um arquivo yml, ou um banco de dados sqlite, ou um servidor central … O objetivo é manter isso completamente separado do próprio aplicativo Rails.
Essa é uma boa prática para configuração que também não é sensível, porque permite personalizar cada instância do servidor da maneira que desejar, sem ter que criar novos grupos no arquivo database.yml ou em outros lugares.