Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
linux:rails_with_puma_deploy [2017/09/05 11:43] 1891982 [Coloque o puma para ser iniciado automaticamente no boot da máquina] |
linux:rails_with_puma_deploy [2021/08/25 10:33] |
||
---|---|---|---|
Linha 1: | Linha 1: | ||
- | ===== Publicando aplicação rails em produção usando Ubuntu + Rails 5 + Nginx + Puma + PostgreSQL + Capistrano 3 ===== | ||
- | |||
- | Puma é um servidor HTTP 1.1 de aplicações Ruby/Rack, simples, rápido, que utiliza threads e altamente concorrente. Puma é indicado para uso tanto em ambientes de desenvolvimento quanto de produção. Atualmente é preferível fazer deploy de aplicações Rails utilizando o Puma devido a sua performance superior. | ||
- | |||
- | Entre na máquina via ssh | ||
- | < | ||
- | $ ssh usuario@app_name.ifce.edu.br | ||
- | </ | ||
- | Obs: Caso a chave ssh do servidor tenha sido alterada, por algum motivo específico, | ||
- | |||
- | < | ||
- | rm ~/ | ||
- | </ | ||
- | |||
- | ==== Criando usuário da aplicação ==== | ||
- | |||
- | É recomendado criar um usuário na máquina com o mesmo nome da aplicação, | ||
- | |||
- | Crie o usuário | ||
- | |||
- | < | ||
- | sudo adduser minha_app | ||
- | </ | ||
- | |||
- | Digite a senha e as informações necessárias até finalizar o processo | ||
- | |||
- | Adicione o usuário ao arquivo sudoers: | ||
- | |||
- | < | ||
- | sudo visudo | ||
- | </ | ||
- | |||
- | No final do arquivo adicione: | ||
- | |||
- | < | ||
- | minha_app ALL=(ALL) NOPASSWD: | ||
- | </ | ||
- | |||
- | Digite Ctrl + O para salvar e depois Ctrl + X para fechar o arquivo | ||
- | |||
- | Logue com esse novo usuário | ||
- | |||
- | < | ||
- | su minha_app | ||
- | </ | ||
- | |||
- | Troque o dono do diretório de deploy que utilizaremos: | ||
- | |||
- | < | ||
- | sudo chown -R minha_app: | ||
- | </ | ||
- | |||
- | ==== Adicione sua chave ssh ao servidor para se logar sem senha: ==== | ||
- | |||
- | Dê ssh para alguma máquina a fim de criar o diretório ~/.ssh | ||
- | |||
- | < | ||
- | ssh usuario@app_name.ifce.edu.br | ||
- | </ | ||
- | |||
- | Dê um Ctrl+C ao ser solicitado pela senha. | ||
- | |||
- | Adicione sua chave ao arquivo ~/ | ||
- | |||
- | Na sua máquina local pegue a sua chave ssh se existir com o comando (Cuidado para não copiar os espaços): | ||
- | |||
- | < | ||
- | cat ~/ | ||
- | </ | ||
- | |||
- | No servidor adicione a chave ao arquivo: | ||
- | |||
- | < | ||
- | vim ~/ | ||
- | </ | ||
- | |||
- | Cole conteúdo da chave nesse arquivo | ||
- | |||
- | Salve e teste | ||
- | |||
- | ==== Instalando o RVM ==== | ||
- | |||
- | **Corrigindo possíveis problemas de dns na máquina** | ||
- | |||
- | Edite o arquivo / | ||
- | |||
- | < | ||
- | dns-nameservers 8.8.8.8 | ||
- | dns-nameservers 8.8.4.4 | ||
- | dns-nameservers 200.17.33.7 | ||
- | dns-search ifce.edu.br | ||
- | </ | ||
- | |||
- | Reinicie a máquina: | ||
- | |||
- | < | ||
- | sudo reboot | ||
- | </ | ||
- | |||
- | |||
- | |||
- | **Instalando o Curl** | ||
- | |||
- | < | ||
- | $ sudo apt-get update | ||
- | $ sudo apt-get install curl | ||
- | </ | ||
- | |||
- | <fc #ff0000> | ||
- | Obs: caso tenha algum problema ao baixar o rvm, verifique os seus servidores DNS no arquivo: / | ||
- | </fc> | ||
- | |||
- | < | ||
- | $ curl -L get.rvm.io | bash -s stable | ||
- | </ | ||
- | |||
- | |||
- | Caso ocorra o seguinte erro, rode o comando sugerido pelo próprio erro: | ||
- | |||
- | GPG signature verification failed for '/ | ||
- | try downloading the signatures: | ||
- | |||
- | Rode: | ||
- | |||
- | < | ||
- | curl -sSL https:// | ||
- | </ | ||
- | |||
- | E depois rode novamente os comandos abaixo para finalizar a instalação do rvm: | ||
- | |||
- | < | ||
- | $ curl -L get.rvm.io | bash -s stable | ||
- | </ | ||
- | |||
- | Agora é preciso instalar os requisitos para instalar o ruby e instalar também a gem bundles para gerenciar as outras gems do projeto: | ||
- | |||
- | < | ||
- | $ source ~/ | ||
- | $ rvm requirements | ||
- | $ rvm install 2.0.0 (Utilize a versão que vc estiver trabalhando no projeto atual) | ||
- | $ rvm use 2.0.0 --default | ||
- | $ rvm rubygems current | ||
- | $ gem install bundler | ||
- | </ | ||
- | |||
- | ==== Instale a lib de dependência do PostgreSQL, Imagemagick e Git ==== | ||
- | |||
- | |||
- | < | ||
- | $ sudo apt-get install libpq-dev imagemagick git-core | ||
- | </ | ||
- | |||
- | Crie o usuário do postgresql da forma que você preferir | ||
- | |||
- | Crie o Banco de Dados do Sistema no Postgresql | ||
- | |||
- | |||
- | ==== Instalando e configurando o Nginx ==== | ||
- | |||
- | < | ||
- | $ sudo apt-get install nginx | ||
- | $ sudo service nginx start | ||
- | $ sudo service nginx status (Ele deve estar rodando agora!) | ||
- | </ | ||
- | |||
- | ==== Adicionando configuração de deploy na aplicação ==== | ||
- | |||
- | Adicione o código abaixo no Gemfile da sua aplicação: | ||
- | |||
- | < | ||
- | # Javascript runtime | ||
- | gem ' | ||
- | |||
- | group : | ||
- | gem ' | ||
- | gem ' | ||
- | gem ' | ||
- | gem ' | ||
- | gem ' | ||
- | end | ||
- | |||
- | gem ' | ||
- | </ | ||
- | |||
- | Instale as novas gems: | ||
- | |||
- | < | ||
- | bundle install | ||
- | </ | ||
- | |||
- | Crie os arquivos do capistrano na sua aplicação usando o comando abaixo: | ||
- | |||
- | < | ||
- | cap install | ||
- | </ | ||
- | |||
- | Substitua o conteúdo do arquivo Capfile pelo código abaixo: | ||
- | |||
- | < | ||
- | # Load DSL and set up stages | ||
- | require " | ||
- | |||
- | # Include default deployment tasks | ||
- | require " | ||
- | |||
- | require " | ||
- | install_plugin Capistrano:: | ||
- | |||
- | # Adittional plugins | ||
- | require ' | ||
- | require " | ||
- | require " | ||
- | require " | ||
- | install_plugin Capistrano:: | ||
- | install_plugin Capistrano:: | ||
- | require " | ||
- | require " | ||
- | require ' | ||
- | require ' | ||
- | |||
- | |||
- | # Load custom tasks from `lib/ | ||
- | Dir.glob(" | ||
- | </ | ||
- | |||
- | |||
- | Substitua o conteúdo do arquivo config/ | ||
- | |||
- | |||
- | < | ||
- | # Change these | ||
- | server ' | ||
- | |||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | |||
- | # Don't change these unless you know what you're doing | ||
- | set :pty, true | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | set : | ||
- | |||
- | namespace :deploy do | ||
- | desc "Make sure local git is in sync with remote." | ||
- | task : | ||
- | on roles(:app) do | ||
- | unless `git rev-parse HEAD` == `git rev-parse origin/ | ||
- | puts " | ||
- | puts "Run `git push` to sync changes." | ||
- | exit | ||
- | end | ||
- | end | ||
- | end | ||
- | |||
- | desc ' | ||
- | task : | ||
- | on roles(:app) do | ||
- | sudo "ln -nfs # | ||
- | sudo "chmod +x / | ||
- | execute "ln -nfs # | ||
- | execute "ln -sf # | ||
- | execute "ln -sf # | ||
- | execute "ln -sf # | ||
- | end | ||
- | end | ||
- | |||
- | desc ' | ||
- | task : | ||
- | on roles(:app) do | ||
- | execute "cd # | ||
- | execute "cd # | ||
- | end | ||
- | end | ||
- | |||
- | after " | ||
- | after " | ||
- | before : | ||
- | after : | ||
- | after : | ||
- | end | ||
- | |||
- | </ | ||
- | |||
- | Crie o arquivo config/ | ||
- | |||
- | < | ||
- | upstream puma { | ||
- | server unix:/// | ||
- | } | ||
- | |||
- | server { | ||
- | listen 80 default_server deferred; | ||
- | |||
- | root / | ||
- | access_log / | ||
- | error_log / | ||
- | |||
- | location ^~ /assets/ { | ||
- | gzip_static on; | ||
- | expires max; | ||
- | add_header Cache-Control public; | ||
- | } | ||
- | |||
- | try_files $uri/ | ||
- | location @puma { | ||
- | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
- | proxy_set_header Host $http_host; | ||
- | proxy_redirect off; | ||
- | |||
- | proxy_pass http:// | ||
- | } | ||
- | |||
- | error_page 500 502 503 504 /500.html; | ||
- | client_max_body_size 10M; | ||
- | keepalive_timeout 10; | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Coloque o puma para ser iniciado automaticamente no boot da máquina ==== | ||
- | |||
- | Crie o arquivo config/ | ||
- | |||
- | < | ||
- | # | ||
- | directory '/ | ||
- | rackup "/ | ||
- | environment ' | ||
- | |||
- | pidfile "/ | ||
- | state_path "/ | ||
- | stdout_redirect '/ | ||
- | |||
- | threads 4,16 | ||
- | |||
- | bind ' | ||
- | |||
- | workers 4 | ||
- | |||
- | preload_app! | ||
- | |||
- | on_restart do | ||
- | puts ' | ||
- | ENV[" | ||
- | end | ||
- | |||
- | |||
- | on_worker_boot do | ||
- | ActiveSupport.on_load(: | ||
- | ActiveRecord:: | ||
- | end | ||
- | end | ||
- | </ | ||
- | |||
- | Crie o arquivo config/ | ||
- | |||
- | |||
- | < | ||
- | #! /bin/sh | ||
- | |||
- | ### BEGIN INIT INFO | ||
- | # Provides: | ||
- | # Required-Start: | ||
- | # Required-Stop: | ||
- | # Default-Start: | ||
- | # Default-Stop: | ||
- | # Short-Description: | ||
- | # Description: | ||
- | ### END INIT INFO | ||
- | |||
- | PUMA_WORKING_DIRECTORY=/ | ||
- | PUMA_CONFIG_FILE=config/ | ||
- | PUMA_PID_FILE=/ | ||
- | PUMA_SOCKET_FILE=/ | ||
- | PUMA_USER=< | ||
- | |||
- | puma_is_running() { | ||
- | if [ -S $PUMA_SOCKET_FILE ] && [ -e $PUMA_PID_FILE ] && cat $PUMA_PID_FILE | xargs pgrep -P > /dev/null; then | ||
- | return 0 | ||
- | else | ||
- | return 1 | ||
- | fi | ||
- | } | ||
- | |||
- | case " | ||
- | start) | ||
- | if puma_is_running; | ||
- | echo "Puma is running" | ||
- | else | ||
- | su -c "cd $PUMA_WORKING_DIRECTORY && bundle exec puma -C $PUMA_CONFIG_FILE --daemon" | ||
- | echo "Puma started" | ||
- | fi | ||
- | ;; | ||
- | stop) | ||
- | if puma_is_running; | ||
- | su -c "kill -s SIGTERM `cat $PUMA_PID_FILE`" | ||
- | rm -f $PUMA_PID_FILE | ||
- | rm -f $PUMA_SOCKET_FILE | ||
- | echo "Puma stopped" | ||
- | else | ||
- | echo "Puma is not running" | ||
- | fi | ||
- | ;; | ||
- | restart) | ||
- | if puma_is_running; | ||
- | su -c "kill -s SIGUSR2 `cat $PUMA_PID_FILE`" | ||
- | echo "Puma restarted" | ||
- | else | ||
- | echo "Puma is not running" | ||
- | fi | ||
- | ;; | ||
- | status) | ||
- | if puma_is_running; | ||
- | echo "Puma is running" | ||
- | exit 0 | ||
- | else | ||
- | echo "Puma is not running" | ||
- | exit 1 | ||
- | fi | ||
- | ;; | ||
- | *) | ||
- | echo " | ||
- | exit 1 | ||
- | ;; | ||
- | esac | ||
- | </ | ||
- | |||
- | |||
- | ==== Gere e Adicione a chave ssh do servidor no repositório git remoto (no caso o gitlab do ifce) ==== | ||
- | |||
- | |||
- | Entre no diretório do ssh do servidor: | ||
- | |||
- | < | ||
- | cd ~/.ssh && ls | ||
- | </ | ||
- | |||
- | Verifique se o arquivo **id_rsa.pub** já existe. Caso não existe você deve criá-lo com o seguinte comando: | ||
- | |||
- | < | ||
- | ssh-keygen -t rsa -C " | ||
- | </ | ||
- | |||
- | Apenas fique apertando Enter nos prompts que serão exibidos. Não precisa digitar nada. | ||
- | Agora você precisa copiar o conteúdo da chave pública: **id_rsa.pub** para o repositório git (no caso o gitlab do ifce) | ||
- | |||
- | < | ||
- | Vá no Projeto > Settings > Repository > Deploy Keys e crie uma nova, colando o conteúdo da chave no campo Key. | ||
- | </ | ||
- | |||
- | Adicione a chave ssh ao seu identity provider | ||
- | |||
- | < | ||
- | ssh-add ~/ | ||
- | </ | ||
- | |||
- | |||
- | ==== Deploy inicial da estrutura (criação da estrutura de diretórios inicial) ==== | ||
- | |||
- | Comite todas as mudanças no projeto | ||
- | |||
- | < | ||
- | git add -A . | ||
- | git commit -m " | ||
- | git push origin master | ||
- | </ | ||
- | |||
- | Execute o deploy inicial que irá criar a estrutura de diretórios do capistrano | ||
- | |||
- | < | ||
- | cap production deploy: | ||
- | </ | ||
- | |||
- | Crie o diretório / | ||
- | |||
- | < | ||
- | mkdir / | ||
- | touch database.yml | ||
- | touch secrets.yml | ||
- | </ | ||
- | |||
- | Crie o diretório tmp e tmp/sockets | ||
- | |||
- | < | ||
- | mkdir / | ||
- | mkdir / | ||
- | mkdir / | ||
- | </ | ||
- | |||
- | <fc #ff0000> | ||
- | Obs: Deverão ocorrer erros no deploy inicial. Caso ocorram, siga os passos abaixo e depois execute um deploy normal, usando: cap production deploy. (Esse comando executado acima, foi apenas para criar a estrutura inicial do deploy, ele dá erro mesmo, é normal.) | ||
- | </fc> | ||
- | |||
- | |||
- | |||
- | ==== Configurações finais de deploy ==== | ||
- | |||
- | * Rode o comando abaixo na máquina remota para configurar o nginx | ||
- | |||
- | < | ||
- | sudo ln -nfs "/ | ||
- | </ | ||
- | |||
- | |||
- | * Adicione a configuração do ambiente correspondente (production ou staging) ao arquivo: | ||
- | |||
- | < | ||
- | / | ||
- | </ | ||
- | |||
- | * Adicione as configurações abaixo(no projeto local) no arquivo config/ | ||
- | |||
- | < | ||
- | config.action_mailer.delivery_method = :smtp | ||
- | config.action_mailer.default_url_options = { :host => ' | ||
- | |||
- | ActionMailer:: | ||
- | ActionMailer:: | ||
- | : | ||
- | : | ||
- | :port => 25, | ||
- | : | ||
- | } | ||
- | </ | ||
- | |||
- | * Adicione o token do devise (no seu projeto local) em config/ | ||
- | |||
- | < | ||
- | config.secret_key = < | ||
- | </ | ||
- | |||
- | |||
- | <fc #ff0000> | ||
- | Você deve gerar essa chave na sua máquina local usando o comando: rake secret | ||
- | </fc> | ||
- | |||
- | |||
- | * Crie o arquivo / | ||
- | |||
- | < | ||
- | production: | ||
- | secret_key_base: | ||
- | </ | ||
- | |||
- | |||
- | <fc #ff0000> | ||
- | Você deve gerar essa chave na sua máquina local usando o comando: rake secret | ||
- | </fc> | ||
- | |||
- | |||
- | <fc #ff0000> | ||
- | Após realizar as mudanças no seu projeto local, não esqueça de comitá-las e dar um push para o git remoto. | ||
- | </fc> | ||
- | |||
- | |||
- | * Remova o site padrão do nginx | ||
- | |||
- | < | ||
- | sudo rm / | ||
- | </ | ||
- | |||
- | * Reinicie o nginx | ||
- | |||
- | < | ||
- | sudo service nginx restart | ||
- | </ | ||
- | |||
- | * Se você usa sidekiq no seu projeto instale o monit: | ||
- | |||
- | < | ||
- | sudo apt-get install monit | ||
- | </ | ||
- | |||
- | Configure o monit para suportar a interface http | ||
- | |||
- | Edite o arquivo: / | ||
- | |||
- | < | ||
- | set httpd port 2812 and | ||
- | use address localhost | ||
- | allow localhost | ||
- | allow admin:monit | ||
- | </ | ||
- | |||
- | Reinicie o monit | ||
- | |||
- | < | ||
- | sudo / | ||
- | </ | ||
- | |||
- | * Deploy | ||
- | |||
- | < | ||
- | $ cap production deploy | ||
- | </ | ||
- | |||
- | * Coloque o puma para ser iniciado automaticamente no boot da máquina | ||
- | |||
- | < | ||
- | sudo update-rc.d puma_< | ||
- | </ | ||