Created
May 15, 2013 14:39
-
-
Save arferreira/5584469 to your computer and use it in GitHub Desktop.
Configuração ruby, nginx e unicorn (Digital Ocean - Ubuntu 12.04.x64 server)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Atualização do Ubuntu | |
Quando instalamos a versão do SO, é claro que esta não vem totalmente atualizada, por isso iremos dar uma arrumada na casa e deixar tudo preparado. | |
# efetua o download de uma lista de pacotes atualizados | |
sudo apt-get update | |
# faz o upgrade da distribuição que tens (dapper). | |
sudo apt-get upgrade | |
# faz o upgrade para a distribuição imediatamente a seguir (edgy). | |
sudo apt-get dist-upgrade | |
# remove os pacotes não mais usados. | |
sudo apt-get autoremove | |
# reinicia o servidor para aplicar as atualizações. | |
sudo reboot | |
GCC e Git | |
Precisaremos do pacote de compiladores chamado GCC e do Git para o nosso controle de versão. | |
sudo apt-get install build-essential git-core | |
Usuário de deploy | |
Normalmente criamos um usuário para ficar responsável pelo deploy, tendo somente permissão de manipulação dos arquivos referentes a um determinado sistema. Este usuário, chamado deploy, deve pertencer a um grupo restrito chamado www-data. | |
sudo adduser --ingroup www-data deploy | |
Infelizmente tive problemas para trabalhar com esse usuário, pois somos obrigado a logar com o usuário, ubuntu, padrão que vem na imagem da EC2. Por isso utilizarei este usuário padrão. Caso tenha alguma dica, deixe o seu comentário. (: | |
Configuração de Path | |
Precisamos especifar alguns paths editando o profile: | |
sudo vim /etc/profile | |
E adicionando o seguinte conteúdo: | |
export PATH=/opt/local/bin:/opt/local/sbin:/opt/local/ruby/gems/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin | |
export RAILS_ENV=production | |
export GEM_HOME=/opt/local/ruby/gems | |
export LC_ALL=en_US.UTF-8 | |
Não se preocupe com as pastas *bin adicionadas ao path, pois não irá avacalhar a segurança. Lá teremos alguns programas que iremos instalar a seguir. Também dizemos que o ambiente Rails será de produção, onde estará as gems e a lingua juntamente com o encode da aplicação. | |
Adicione no arquivo environment o mesmo conteúdo: | |
sudo vim /etc/environment | |
export PATH=/opt/local/bin:/opt/local/sbin:/opt/local/ruby/gems/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin | |
RAILS_ENV=production | |
GEM_HOME=/opt/local/ruby/gems | |
LC_ALL=en_US.UTF-8 | |
E para finalizar editamos o sudoers e substituimos o valor da variável secure_path existente para o mesmo path que utilizamos acima: | |
sudo vim /etc/sudoers | |
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/local/bin:/opt/local/sbin:/opt/local/ruby/gems/bin" | |
Ruby | |
Se você já pensou no RVM, sem problemas. Também utilizo o mesmo localmente, porém no servidor iremos compilar tudo, deixando tudo bem enxuto. (: | |
Vamos instalar algumas dependências do Ruby: | |
sudo apt-get install libyaml-dev libssl-dev libreadline-dev libxml2-dev libxslt1-dev libffi-dev | |
E criar uma pasta src onde deixaremos os sources das aplicações que iremos instalar: | |
sudo mkdir -p /opt/local/src | |
cd /opt/local/src | |
Então podemos fazer o download e acessar o seu conteúdo: | |
sudo wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p286.tar.bz2 | |
sudo tar xvf ruby-1.9.3-p286.tar.bz2 | |
cd /opt/local/src/ruby-1.9.3-p286 | |
Agora podemos iniciar a instalação: | |
sudo ./configure --prefix=/opt/local/ruby/1.9.3 | |
sudo make && sudo make install | |
Vá tomar um café... | |
Se você já usou MacOSX sabe que a parte de versionamento dos programas é bem legal, então vamos adotar isso e versionar a versão do Ruby, assim como os outros programas, em nosso servidor. Sendo assim criaremos um link simbólico chamado de current, indicando a versão corrente do sistema: | |
sudo ln -s /opt/local/ruby/1.9.3 /opt/local/ruby/current | |
sudo ln -s /opt/local/src/ruby-1.9.3-p286 /opt/local/ruby/current | |
Todas as nossas aplicações ficarão centralizadas em suas pastas, mas terão um link simbólico para a pasta bin e sbin, logo iremos criá-las: | |
sudo mkdir -p /opt/local/bin | |
sudo mkdir -p /opt/local/sbin | |
E então podemos criar os links simbólicos para a pasta bin: | |
sudo ln -s /opt/local/ruby/current/bin/erb /opt/local/bin/erb | |
sudo ln -s /opt/local/ruby/current/bin/gem /opt/local/bin/gem | |
sudo ln -s /opt/local/ruby/current/bin/irb /opt/local/bin/irb | |
sudo ln -s /opt/local/ruby/current/bin/rake /opt/local/bin/rake | |
sudo ln -s /opt/local/ruby/current/bin/rdoc /opt/local/bin/rdoc | |
sudo ln -s /opt/local/ruby/current/bin/ri /opt/local/bin/ri | |
sudo ln -s /opt/local/ruby/current/bin/ruby /opt/local/bin/ruby | |
sudo ln -s /opt/local/ruby/current/bin/testrb /opt/local/bin/testrb | |
E para a pasta sbin: | |
sudo ln -s /opt/local/ruby/current/sbin/erb /opt/local/sbin/erb | |
sudo ln -s /opt/local/ruby/current/sbin/gem /opt/local/sbin/gem | |
sudo ln -s /opt/local/ruby/current/sbin/irb /opt/local/sbin/irb | |
sudo ln -s /opt/local/ruby/current/sbin/rake /opt/local/sbin/rake | |
sudo ln -s /opt/local/ruby/current/sbin/rdoc /opt/local/sbin/rdoc | |
sudo ln -s /opt/local/ruby/current/sbin/ri /opt/local/sbin/ri | |
sudo ln -s /opt/local/ruby/current/sbin/ruby /opt/local/sbin/ruby | |
sudo ln -s /opt/local/ruby/current/sbin/testrb /opt/local/sbin/testrb | |
Pode ser que alguns arquivos não existam na pasta bin ou sbin e tentar todos manualmente é um pouco chato, mas quem disse que todos esses comandos não podem ser automatizados em um simples .sh? Lembre-se que este artigo é didático, por isso esta passo-a-passo para você entender como tudo funciona. (; | |
Verifique se tudo deu certo: | |
ruby -v | |
# ruby 1.9.3p286 (2012-10-12 revision 37165) [x86_64-linux] | |
Caso seja listada algumas versões e não apareça a versão semelhante com o descrito acima, basta se reconectar ao servidor. | |
RubyGems | |
O RubyGems é um repositório de gems no qual iremos fazer o download automáticos das nossas gems. Podemos criar um arquivo chamado gemrc para fazermos algumas configurações relacionadas as gem. Para isso crie esse arquivo: | |
vim ~/.gemrc | |
E então iremos apontar o caminho de onde ficará armazenado nossas gems e também dizer que não queremos baixar suas documentações: | |
gemhome: '/opt/local/ruby/gems' | |
gempath: | |
- /opt/local/ruby/gems | |
gem: '--no-rdoc --no-ri' | |
O rdoc é uma ótima ferramenta para consultar a documentação, porém isso não será feito no servidor né? | |
Agora podemos fazer uma atualização: | |
sudo gem update --system | |
Bundler | |
O Bundler é uma ferramenta para garantir a atualização correta das nossas gems, e iremos instalá-lo: | |
sudo gem install bundler | |
Nginx | |
Temos boas opção de servidores web para aplicações Ruby como é o caso do Apache, mas por vários motivos iremos utilizar o Nginx. O processo é praticamente igual ao da instalação do Ruby, no qual baixamos o source, instalamos e criamos os links. | |
Vamos instalamos algumas depedência antes: | |
sudo apt-get install libpcre3-dev libssl-dev | |
E então baixamos o source: | |
sudo wget http://nginx.org/download/nginx-1.3.7.tar.gz | |
sudo tar xvf nginx-1.3.7.tar.gz | |
cd nginx-1.3.7 | |
Vamos passar algumas configurações importantes: | |
sudo ./configure --prefix=/opt/local/nginx/1.3.7 \ | |
--with-http_ssl_module --with-http_realip_module \ | |
--with-http_gzip_static_module --conf-path=/etc/nginx/nginx.conf \ | |
--error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx.pid \ | |
--lock-path=/var/lock/nginx.lock --http-log-path=/var/log/nginx/access.log \ | |
--http-client-body-temp-path=/var/lib/nginx/body \ | |
--http-proxy-temp-path=/var/lib/nginx/proxy \ | |
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi --with-debug --with-ipv6 | |
Nesta configuração adicionamos módulos usando o prefixo --with- e setamos caminhos com o sufixo -path. Vamos analisar algumas configurações: | |
--conf-path: Caminho do arquivo de configuração do gzip e afins. | |
--error-log-path: Caminho do arquivo de log erro. | |
--http-client-body-temp-path: -- | |
--http-fastcgi-temp-path: -- | |
--http-log-path: Caminho do log de acesso. | |
--http-proxy-temp-path: -- | |
--lock-path: -- | |
--pid-path: Caminho do PID. | |
--prefix: Caminho dos arquivos do NGINX. | |
--with-debug: Nível de log. Os mais importante: [debug, info, notice, warn, error, crit] | |
--with-http_gzip_static_module: -- | |
--with-http_realip_module: -- | |
--with-http_ssl_module: -- | |
--with-ipv6: -- | |
E então iniciar a compilação e instalação: | |
sudo make && sudo make install | |
Como boa prática iremos criar o link da versão corrente como já havíamos feito com o Ruby: | |
sudo ln -s /opt/local/nginx/1.3.7 /opt/local/nginx/current | |
E criar os links simbólicos: | |
sudo ln -s /opt/local/nginx/current/bin/nginx /opt/local/bin/nginx | |
sudo ln -s /opt/local/nginx/current/sbin/nginx /opt/local/sbin/nginx | |
Verifique se tudo deu certo: | |
nginx -v | |
# nginx version: nginx/1.3.7 | |
É possível ver as informações completas incluindo os módulos instalando utilizando a letra 'v' maiúscula. O que ajuda muito caso queiramos alterar algum módulo: | |
nginx -V | |
Ngnix (pastas) | |
Precisamos de deferentes pastas para armazenar as configurações, PID entre outros cousas do Nginx. Como estamos utilizando o usuário ubuntu, vamos sempre dar permissão para este. | |
Primeiro iremos criar a famosa pasta www onde ficará armazenado o nosso sistema: | |
sudo mkdir /var/www | |
sudo chown ubuntu:ubuntu /var/www | |
sudo chmod 774 /var/www | |
E então criar as pastas onde ficarão as configurações: | |
sudo mkdir -p /var/lib/nginx/body | |
sudo mkdir -p /var/lib/nginx/proxy | |
sudo mkdir -p /var/lib/nginx/fastcgi | |
sudo chown -R ubuntu:ubuntu /var/lib/nginx | |
sudo mkdir -p /var/log/nginx/ | |
sudo chown ubuntu:ubuntu /var/log/nginx | |
sudo mkdir /etc/nginx/ssl | |
sudo mkdir /etc/nginx/sites-enabled | |
Nginx (conf) | |
Vamos editar o arquivo de configuração: | |
sudo vim /etc/nginx/nginx.conf | |
Haverá uma configuração default lá, porém iremos substituí-la pela seguinte: | |
# O user e o group que irá rodar o serviço. | |
user ubuntu ubuntu; | |
# Quantidade de worker que inicializamos que por default são 2. | |
# É recomendado setar este valor para o número de cores disponíve no servidor. | |
worker_processes 4; | |
# O mesmo caminho do PID que determinamos na configuração de instalação. | |
pid /var/run/nginx.pid; | |
events { | |
# Quantidade de conexões que cada worker pode abrir. A multiplicação processes * connections | |
# resulta no máximo de clientes acessando a aplicação. | |
worker_connections 1024; | |
} | |
http { | |
include /etc/nginx/mime.types; | |
default_type application/octet-stream; | |
log_format main '$remote_addr - $remote_user [$time_local] ' | |
'"$request" $status $body_bytes_sent "$http_referer" ' | |
'"$http_user_agent" "$http_x_forwarded_for"'; | |
sendfile on; | |
keepalive_requests 10; | |
keepalive_timeout 60; | |
tcp_nodelay off; | |
tcp_nopush on; | |
ignore_invalid_headers on; | |
send_timeout 60; | |
gzip on; | |
gzip_http_version 1.0; | |
gzip_comp_level 6; | |
gzip_proxied any; | |
gzip_types text/plain text/css application/x-javascript text/xml | |
application/xml application/xml+rss text/javascript; | |
gzip_disable "MSIE [1-6] \."; | |
include /etc/nginx/sites-enabled/*; | |
} | |
Se estiver usando o vim para editar os arquivos, digite: 100 + D + D para apagar 100 linhas. | |
Esta configuração diz respeito ao gzip, quantidade de processos e conexões, caminho do PID e das configurações de cada sistema e principalmente configurações que envolvem timeouts de alguma feature específica. Não vamos entrar em detalhes em cada item para não estender este artigo. | |
Nginx (arquivo do nosso sistema) | |
Como podemos ter mais de um sistema rodando no mesmo Nginx, criamos um arquivo específico para cada um. Vamos criar um arquivo para o blog wbotelhos.com.br: | |
sudo vim /etc/nginx/sites-enabled/wbotelhos-br.conf | |
E colar a seguinte configuração: | |
upstream app { | |
server 127.0.0.1:5000; | |
server 127.0.0.1:5001; | |
server 127.0.0.1:5002; | |
} | |
server { | |
# A porta no qual o servidor esta escutando as requisições. | |
listen 80; | |
# IP ou domínio definido para apontar para o nosso virtual host. | |
server_name ec2-x-p-t-o.sa-east-1.compute.amazonaws.com; | |
# Configurar o root para a pasta "public" é muito importante quando queremos utilizar arquivos | |
# estáticos sem passar pelo Rails como é o caso dos meus plugins (wbotelhos.com/raty). | |
# Como o root da aplicação esta apontando para "public", logo wbotelhos.com/raty aponta | |
# para uma pasta dentro de "public/raty" que é acessada diretamente fora do Rails. | |
# E o melhor é que se você acessar apenas wbotelhos.com com barra no final ou não | |
# o que você definiu no seu routes.rb será processado: `root to: 'articles#index'` | |
root /var/www/wbotelhos-br/current/public; | |
# O "index" é complemento da configuração "root", onde ao acessar wbotelho.com/raty seremos | |
# redirecionados automáticamente para a página public/raty/index.html. | |
# Precisamos dessa configuração, pois não conseguimos acessar a página html diretamente. | |
index index.html; | |
# Tamanho máximo permitido para requisção indicado pelo Content-Length. Default: 1M. | |
client_max_body_size 5M; | |
location / { | |
proxy_set_header X-Real-IP $remote_addr; | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
proxy_set_header Host $http_host; | |
proxy_redirect off; | |
if ($request_uri ~* "\.(ico|css|js|gif|jpe?g|png)\?[0-9]+$") { | |
access_log off; | |
add_header Cache-Control public; | |
expires max; | |
break; | |
} | |
if (-f $request_filename/index.html) { | |
rewrite (.*) $1/index.html break; | |
} | |
if (-f $request_filename.html) { | |
rewrite (.*) $1.html break; | |
} | |
if (!-f $request_filename) { | |
proxy_pass http://app; | |
break; | |
} | |
} | |
error_page 500 502 503 504 /500.html; | |
location = /500.html { | |
root /var/www/wbotelhos-br/current/public; | |
} | |
} | |
Você deve substituir o Public DNS ec2-X-P-T-O.sa-east-1.compute.amazonaws.com pelo DNS da instância que você criou: | |
server_name ec2-X-P-T-O.sa-east-1.compute.amazonaws.com 0.0.0.0; | |
E então estamos utilizando a pasta wbotelhos-br como pasta do nosso sistema, no qual o root será a pasta pública: | |
root /var/www/wbotelhos-br/current/public; | |
Nginx (Upstart) | |
Vamos criar um arquivo de inicialização do Nginx utilizando o Upstart: | |
sudo vim /etc/init/nginx.conf | |
O conteúdo será o seguinte: | |
description "nginx webserver" | |
start on startup | |
stop on shutdown | |
respawn | |
expect fork | |
exec /opt/local/sbin/nginx | |
Verifique se todas as configurações estão corretas: | |
nginx -t | |
Bem provável alguns arquivos criado pelo Nginx ficarão com o usuário e grupo root. Basta passá-los para o usuário ubuntu: | |
sudo chown ubuntu:ubuntu /var/log/nginx/error.log | |
sudo chown ubuntu:ubuntu /var/run/nginx.pid | |
sudo chown ubuntu:ubuntu /var/log/nginx/access.log | |
sudo chown ubuntu:ubuntu /etc/nginx/nginx.conf | |
Se ainda sim continuar algum erro, ignore e bola pra frente. No final dá tudo certo. :P | |
Para parar o serviço use o stop: | |
sudo stop nginx | |
# nginx stop/waiting | |
E para iniciar basta usar o start: | |
sudo start nginx | |
# nginx start/running, process 30308 | |
Certifique-se que o serviço esta rodando: | |
ps aux | grep nginx | |
E então faça o teste acessando o DNS público pelo browser. | |
open http://ec2-X-P-T-O.sa-east-1.compute.amazonaws.com | |
# 404 Not Found --- nginx/1.3.7 | |
Unicorn | |
Configurar o Unicorn é simples e não requer compilação ou algo do tipo. Ao invés disso, apenas declaramos o mesmo no Gemfile do nosso projeto. Vamos criar o arquivo de inicialização do mesmo: | |
sudo vim /etc/init/unicorn.conf | |
description 'unicorn server' | |
pre-start script | |
mkdir -p /var/run/unicorn | |
chown ubuntu:ubuntu /var/run/unicorn | |
chmod 770 /var/run/unicorn | |
mkdir -p /var/log/unicorn | |
chown ubuntu:ubuntu /var/log/unicorn | |
chmod 770 /var/log/unicorn | |
end script | |
start on startup | |
stop on shutdown | |
exec sudo -u ubuntu -g ubuntu sh -c "cd /home/ubuntu/www/wbotelhos-br/current && RAILS_ENV=production GEM_HOME=/opt/local/ruby/gems bundle exec unicorn_rails -c /home/ubuntu/www/wbotelhos-br/config/unicorn.rb" | |
respawn | |
Repare que já apontamos alguns caminhos como a pasta current que manterá a versão corrente do nosso sistema e a pasta config que além de diversas configuração terá um arquivo de configuração do Unicorn. | |
Ainda não temos a pasta wbotelhos-br e nem a pasta config, então vamos criá-las: | |
mkdir -p /var/www/wbotelhos-br/config | |
E então podemos criar as configurações: | |
vim /var/www/wbotelhos-br/config/unicorn.rb | |
worker_processes 3 | |
listen 5000 | |
listen 5001 | |
listen 5002 | |
preload_app true | |
timeout 30 | |
pid '/var/www/wbotelhos-br/shared/pids/unicorn.pid' | |
stderr_path '/var/www/wbotelhos-br/shared/log/unicorn.error.log' | |
stdout_path '/var/www/wbotelhos-br/shared/log/unicorn.out.log' | |
working_directory '/var/www/wbotelhos-br/current' | |
Estas configurações basicamente são os caminhos dos arquivos de log e o diretório onde o servidor irá atuar, além da quantidade de processos e portas em que ele ficará escutando. | |
Deste modo estamos com o Ruby, Nginx e Unicorn prontos para rodar uma aplicação. É claro que iremos precisar de uma tarefa de deploy usando por exemplo, o Capistrano, que será o tema do próximo post. (: | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment