Passe o banco de dados pwd para Rails com uma variável de ambiente

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.