Differences

This shows you the differences between two versions of the page.

Link to this comparison view

installing_and_configuring_nginx_with_puma_and_mysql_for_rails_on_debian_jessie_en [2019/08/08 15:23]
installing_and_configuring_nginx_with_puma_and_mysql_for_rails_on_debian_jessie_en [2019/08/08 15:23] (current)
Line 1: Line 1:
 +====== Installing and Configuring Nginx with Puma + MySQL for Rails on Debian Jessie ======
  
 +Hey guys, here I will show you how to configure the Nginx with Puma and MySQL to host a Rails application.
 +
 +I will consider that you have a minimal Debian Jessie installation, so we need to install some dependencies and prepare the system.
 +
 +Let's configure the repositories
 +<sxh bash>
 +vi /etc/apt/sources.list
 +# OFFICIAL REPOSITORY
 +deb http://httpredir.debian.org/debian jessie main contrib non-free
 +deb-src http://httpredir.debian.org/debian jessie main contrib non-free
 +
 +# SECURITY UPDATE REPOSITORY
 +deb http://security.debian.org/ jessie/updates main contrib non-free
 +deb-src http://security.debian.org/ jessie/updates main contrib non-free
 +
 +# PROPOSE UPDATE REPOSITORY
 +deb http://httpredir.debian.org/debian jessie-proposed-updates main contrib non-free
 +deb-src http://httpredir.debian.org/debian jessie-proposed-updates main contrib non-free
 +</sxh>
 +
 +Now we need to update the repositories
 +<sxh bash>
 +apt-get update
 +</sxh>
 +
 +Now we need to install the Nginx and the git
 +<sxh bash>
 +apt-get install curl vim git-core nginx -y
 +</sxh>
 +
 +===== Installing the MySQL Server =====
 +
 +Now let's update the repositories
 +<sxh bash>
 +apt-get update
 +</sxh>
 +
 +Now let's install the MySQL
 +<sxh bash>
 +apt-get install mysql-server mysql-client libmysqlclient-dev libmysql++-dev libmysqld-dev -y
 +</sxh>
 +
 +**Note:** You will be asked about the root password, so set it up.
 +
 +
 +
 +
 +===== Installing the RVM =====
 +
 +Let's import the rvm gpg key
 +<sxh bash>
 +gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
 +</sxh>
 +
 +Now let's install the rvm to manage our Rubies
 +<sxh bash;>
 +curl -sSL https://get.rvm.io | bash -s stable
 +</sxh>
 +
 +Now if you have more users that will be using the rvm we need to add them into the rvm's group
 +<sxh bash>
 +gpasswd -a douglas rvm
 +</sxh>
 +
 +Now we need to import the environment variables
 +<sxh bash;>
 +source /etc/profile.d/rvm.sh
 +</sxh>
 +
 +Now let's install the dependencies of the rvm
 +<sxh bash>
 +rvm requirements
 +</sxh>
 +
 +Now we need to install the ruby 
 +<sxh bash>
 +rvm install 2.3.0
 +</sxh>
 +
 +Now we need to set as the default
 +<sxh bash>
 +rvm use 2.3.0 --default
 +</sxh>
 +
 +Now we need to install the rails and the bundler
 +<sxh bash>
 +gem install rails -V --no-ri --no-rdoc
 +gem install bundler -V --no-ri --no-rdoc
 +</sxh>
 +
 +Three flags were used:
 +  * <nowiki>-V</nowiki> (Verbose Output): Prints detailed information about Gem installation
 +  * <nowiki>--no-ri</nowiki> - (Skips Ri Documentation): Doesn't install Ri Docs, saving space and making installation fast
 +  * <nowiki>--no-rdoc</nowiki> - (Skips RDocs): Doesn't install RDocs, saving space and speeding up installation
 +
 +**Note:** You can also install a specific version of Rails according to your requirements by using the <nowiki>-v</nowiki> flag:
 +
 +<sxh bash;>
 +gem install rails -v '4.2.0' -V --no-ri --no-rdoc
 +</sxh>
 +
 +Now let's clone a project to use as test
 +<sxh bash>
 +cd /var/www/html && git clone https://github.com/douglasqsantos/dqs-rails-base.git
 +</sxh>
 +
 +Now let's access the project
 +<sxh bash>
 +cd dqs-rails-base/
 +</sxh>
 +
 +Now we need to add the puma into the Gemfile and change the sqlite3 to MySQL
 +<sxh bash;>
 +vim Gemfile
 +ruby '2.3.0'
 +[...]
 +# Use sqlite3 as the database for Active Record
 +#gem 'sqlite3'
 +gem 'mysql2'
 +[...]
 +# Use ActiveModel has_secure_password
 +gem 'bcrypt', '~> 3.1.7'
 +
 +# app server
 +gem 'puma'
 +[...]
 +</sxh>
 +
 +Now let's run the bundler, it will take a little while.
 +<sxh bash>
 +bundle install
 +</sxh>
 +
 +Now we need to create the production key to run the application
 +<sxh bash;>
 +rake secret
 +46d1feba0000226fdf16e9bd94739c7a09fd24401ff8ba33945161fe613a0211459a9167b6267eb796b66167ddf187f4a40a44460a46a9adfeecd875161ea5ac
 +</sxh>
 +
 +Now we need to pass it into config/secrets.yml
 +<sxh bash;>
 +vim config/secrets.yml
 +[...]
 +production:
 +  secret_key_base: b98f316c6a54b6c76ab01859945b78aef9ec0e051e55a30b530957441420057ab3e42fcff7fa308a488a689ee61f10e10ccc07040b190d839f96c7803f50e078
 +</sxh>
 +
 +Now we need to compile the assets
 +<sxh bash;>
 +RAILS_ENV=production rake assets:precompile
 +</sxh>
 +
 +Now let's configure the database connection
 +<sxh yaml>
 +vim config/database.yml
 +default: &default
 +  adapter: mysql2
 +  encoding: utf8
 +  pool: 5
 +  username: dqs_rails
 +  password: 'dqs_rails_passwd'
 +  port: 3306
 +
 +development:
 +  <<: *default
 +  database: dqs_rails_base_dev
 +
 +test:
 +  <<: *default
 +  database: dqs_rails_base_test
 +
 +production:
 +  <<: *default
 +  database: dqs_rails_base_prod
 +</sxh>
 +
 +Now let's create the database
 +<sxh sql>
 +mysql -u root -p
 +CREATE DATABASE dqs-rails-base-prod;
 +GRANT ALL PRIVILEGES ON dqs_rails_base_prod.* to dqs_rails@localhost IDENTIFIED BY 'dqs_rails_passwd';
 +FLUSH PRIVILEGES;
 +quit
 +</sxh>
 +
 +Now we can migrate the database
 +<sxh bash;>
 +RAILS_ENV=production rake db:migrate
 +</sxh>
 +
 +After migrate the database we can seed the database
 +<sxh bash;>
 +RAILS_ENV=production rake db:seed --trace
 +</sxh>
 +
 +Now let's get rid of some warnings that will be generate by the rvm about the ruby version
 +<sxh bash>
 +rvm rvmrc warning ignore allGemfiles
 +</sxh>
 +
 +===== Configuring the Puma =====
 +
 +Before configuring Puma, you should look up the number of CPU cores your server has. You can easily to that with this command:
 +
 +<sxh bash>
 +grep -c processor /proc/cpuinfo
 +</sxh>
 +
 +Now we need to configure the puma server
 +<sxh ruby>
 +vim config/puma.rb
 +# Change to match your CPU core count
 +workers 4
 +
 +# Min and Max threads per worker
 +threads 1, 6
 +
 +app_dir = File.expand_path("../..", __FILE__)
 +shared_dir = "#{app_dir}/shared"
 +
 +# Default to production
 +rails_env = ENV['RAILS_ENV'] || "production"
 +environment rails_env
 +
 +# Set up socket location
 +bind "unix://#{shared_dir}/sockets/puma.sock"
 +
 +# Logging
 +stdout_redirect "#{shared_dir}/log/puma.stdout.log", "#{shared_dir}/log/puma.stderr.log", true
 +
 +# Set master PID and state locations
 +pidfile "#{shared_dir}/pids/puma.pid"
 +state_path "#{shared_dir}/pids/puma.state"
 +activate_control_app
 +
 +on_worker_boot do
 +  require "active_record"
 +  ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
 +  ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[rails_env])
 +end
 +</sxh>
 +
 +Now create the directories that were referred to in the configuration file:
 +
 +<sxh bash;>
 +mkdir -p shared/pids shared/sockets shared/log
 +</sxh>
 +
 +Now let's start the puma server
 +<sxh bash>
 +cd /var/www/html/dqs-rails-base && ( export RACK_ENV="production" ; /usr/local/rvm/bin/rvm default do bundle exec puma -C /var/www/html/dqs-rails-base/config/puma.rb --daemon )
 +</sxh>
 +
 +To stop the puma server
 +<sxh bash>
 +cd /var/www/html/dqs-rails-base && ( export RACK_ENV="production" ; rvm all do bundle exec pumactl -S /var/www/html/dqs-rails-base/shared/pids/puma.state stop )
 +</sxh>
 +
 +===== Configuring the Nginx =====
 +
 +Getting the vim nginx syntax
 +<sxh bash>
 +wget -c https://raw.githubusercontent.com/douglasqsantos/easy-debian/master/nginx.vim -O /usr/share/vim/vim74/syntax/nginx.vim
 +</sxh>
 +
 +Now we need to create the configuration for Nginx
 +<sxh bash;>
 +vim config/nginx.conf
 +# Puma configuration
 +upstream puma {
 +  server unix:///var/www/html/dqs-rails-base/shared/sockets/puma.sock;
 +}
 +
 +# Default server configuration
 +server {
 +  listen 80 default_server deferred;
 +  server_name rails.douglasqsantos.com.br;
 +  server_tokens off;
 +
 +  root /var/www/html/dqs-rails-base/public;
 +  access_log /var/www/html/dqs-rails-base/log/nginx.access.log;
 +  error_log /var/www/html/dqs-rails-base/log/nginx.error.log info;
 +
 +  location ^~ /assets/ {
 +    gzip_static on;
 +    expires max;
 +    add_header Cache-Control public;
 +  }
 +
 +  try_files $uri/index.html $uri @puma;
 +  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://puma;
 +  }
 +
 +  error_page 500 502 503 504 /500.html;
 +  client_max_body_size 10M;
 +  keepalive_timeout 10;
 +}
 +</sxh>
 +
 +Now let's remove the default site for Nginx
 +<sxh bash;>
 +rm /etc/nginx/sites-enabled/default
 +ln -nfs "/var/www/html/dqs-rails-base/config/nginx.conf" "/etc/nginx/sites-enabled/rails"
 +</sxh>
 +
 +Now let's start the Puma server
 +<sxh bash>
 +cd /var/www/html/dqs-rails-base && ( export RACK_ENV="production" ; /usr/local/rvm/bin/rvm default do bundle exec puma -C /var/www/html/dqs-rails-base/config/puma.rb --daemon )
 +</sxh>
 +
 +Now let's restart the Nginx Server
 +<sxh bash;>
 +systemctl restart nginx
 +</sxh>
 +
 +Now we can check the status of the service
 +<sxh bash;>
 +systemctl status nginx
 +</sxh>
 +
 +Now we can check the status of the app
 +http://ip_server or http://rails.douglasqsantos.com.br
 +
 +Now let's create a script to handle the puma service
 +<sxh bash>
 +vim /var/www/html/dqs-rails-base/bin/handle_puma.sh
 +#!/bin/bash
 +#-------------------------------------------------------------------------
 +# Name: /var/www/html/dqs-rails-base/bin/handle_puma.sh
 +#
 +# Site: http://wiki.douglasqsantos.com.br
 +# Autor: Douglas Quintiliano dos Santos <douglas.q.santos@gmail.com>
 +# Management: Douglas Quintiliano dos Santos <douglas.q.santos@gmail.com>
 +#
 +#-------------------------------------------------------------------------
 +# License: [MIT license](http://opensource.org/licenses/MIT)
 +#
 +#-------------------------------------------------------------------------
 +
 +### CORES UTILIZADAS NO SCRIPT ###
 +GREY="\033[01;30m"
 +RED="\033[01;31m"
 +GREEN="\033[01;32m"
 +YELLOW="\033[01;33m"
 +BLUE="\033[01;34m"
 +PURPLE="\033[01;35m"
 +CYAN="\033[01;36m"
 +WHITE="\033[01;37m"
 +CLOSE="\033[m"
 +
 +case $1 in
 +    start)
 +        echo -e "${GREEN}[        Starting Puma         ]${CLOSE}"
 +        cd /var/www/html/dqs-rails-base && ( export RACK_ENV="production" ; /usr/local/rvm/bin/rvm default do bundle exec puma -C /var/www/html/dqs-rails-base/config/puma.rb --daemon )
 +        echo -e "${GREEN}[        Puma Started          ]${CLOSE}"
 +    ;;
 +    stop)
 +        echo -e "${RED}[        Stopping Puma         ]${CLOSE}"
 +       cd /var/www/html/dqs-rails-base && ( export RACK_ENV="production" ; rvm all do bundle exec pumactl -S /var/www/html/dqs-rails-base/shared/pids/puma.state stop )
 +        echo -e "${RED}[        Puma Stopped Puma     ]${CLOSE}"
 +    ;;
 +    restart)
 +        echo -e "${GREEN}[        Restarting Puma       ]${CLOSE}"
 +          $0 stop
 +          $0 start
 +        echo -e "${GREEN}[        Puma Restarted        ]${CLOSE}"
 +    ;;
 +    *)
 +      echo -e "${RED} Valid Options: (start|stop|restart) ${CLOSE}"
 +    ;;
 +esac
 +</sxh>
 +
 +Now we need to give the correct permission to the script
 +<sxh bash>
 +chmod +x /var/www/html/dqs-rails-base/bin/handle_puma.sh
 +</sxh>
 +
 +Now we can call the script such as
 +<sxh bash>
 +/var/www/html/dqs-rails-base/bin/handle_puma.sh start
 +/var/www/html/dqs-rails-base/bin/handle_puma.sh stop
 +/var/www/html/dqs-rails-base/bin/handle_puma.sh restart
 +</sxh>
 +
 +===== Configuring the SystemD to handle the Puma =====
 +
 +Let's create the service
 +<sxh bash>
 +vim /etc/systemd/system/puma.service
 +[Unit]
 +Description=Puma Control
 +After=network.target auditd.service
 +
 +[Service]
 +Type=oneshot
 +RemainAfterExit=yes
 +ExecStart=/etc/puma/puma-start
 +ExecStop=/etc/puma/puma-stop
 +
 +[Install]
 +WantedBy=multi-user.target
 +</sxh>
 +
 +Now we need to create the directory that will store the scripts
 +<sxh bash>
 +mkdir /etc/puma
 +</sxh>
 +
 +Now let's create the script that will start the service
 +<sxh bash>
 +vim /etc/puma/puma-start
 +#!/bin/bash
 +
 +cd /var/www/html/dqs-rails-base && ( export RACK_ENV="production" ; /usr/local/rvm/bin/rvm all do bundle exec puma -C /var/www/html/dqs-rails-base/config/puma.rb --daemon )
 +
 +</sxh>
 +
 +Now let's give the permission to the script
 +<sxh bash>
 +chmod +x /etc/puma/puma-start
 +</sxh>
 +
 +Now let's create the script that will stop the service
 +<sxh bash>
 +vim /etc/puma/puma-stop
 +#!/bin/bash
 +
 +cd /var/www/html/dqs-rails-base && ( export RACK_ENV="production" ; /usr/local/rvm/bin/rvm all do bundle exec pumactl -S /var/www/html/dqs-rails-base/shared/pids/puma.state stop )
 +</sxh>
 +
 +Now let's give the permission to the script
 +<sxh bash>
 +chmod +x /etc/puma/puma-stop
 +</sxh>
 +
 +Now let's enable the service
 +<sxh bash>
 +systemctl enable puma
 +</sxh>
 +
 +Now we can handle the puma service with the systemd
 +<sxh bash>
 +systemctl start puma
 +systemctl stop puma
 +systemctl restart puma
 +systemctl status puma
 +</sxh>
 +
 +Now we can restart the service and check if everything is working properly.
 +
 +===== Enabling the HTTPS =====
 +
 +Now let's enable the https
 +
 +Let's create the directory to store the certificates
 +<sxh bash>
 +mkdir /var/www/html/dqs-rails-base/config/ssl
 +</sxh>
 +
 +Let's access the directory
 +<sxh bash>
 +cd /var/www/html/dqs-rails-base/config/ssl
 +</sxh>
 +
 +Let's create the certificate key
 +<sxh bash>
 +openssl genrsa -des3 -out server.key 1024
 +Generating RSA private key, 1024 bit long modulus
 +..............................++++++
 +.++++++
 +e is 65537 (0x10001)
 +Enter pass phrase for server.key: #PASSWORD
 +Verifying - Enter pass phrase for server.key: #PASSWORD
 +</sxh>
 +
 +Now we need to create the certificate sign request
 +<sxh bash>
 +openssl req -new -key server.key -out server.csr
 +Enter pass phrase for server.key: #PASSWORD
 +You are about to be asked to enter information that will be incorporated
 +into your certificate request.
 +What you are about to enter is what is called a Distinguished Name or a DN.
 +There are quite a few fields but you can leave some blank
 +For some fields there will be a default value,
 +If you enter '.', the field will be left blank.
 +-----
 +Country Name (2 letter code) [AU]:BR
 +State or Province Name (full name) [Some-State]:Parana
 +Locality Name (eg, city) []:Curitiba
 +Organization Name (eg, company) [Internet Widgits Pty Ltd]:DQS
 +Organizational Unit Name (eg, section) []:IT
 +Common Name (e.g. server FQDN or YOUR name) []:rails.douglasqsantos.com.br
 +Email Address []:douglas.q.santos@gmail.com
 +
 +Please enter the following 'extra' attributes
 +to be sent with your certificate request
 +A challenge password []:
 +An optional company name []:DQS
 +</sxh>
 +
 +Now we need to change the certificate permissions
 +<sxh bash>
 +chmod 0400 server.*
 +cp server.key server.key.orig
 +</sxh>
 +
 +Now we need to auto sign the certificate
 +<sxh bash>
 +openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
 +Signature ok
 +subject=/C=BR/ST=Parana/L=Curitiba/O=DQS/OU=IT/CN=rails.douglasqsantos.com.br/emailAddress=douglas.q.santos@gmail.com
 +Getting Private key
 +Enter pass phrase for server.key: #PASSWORD
 +</sxh>
 +
 +Now let's remove the password from our certificate, otherwise we need to put the password every nginx start.
 +<sxh bash>
 +openssl rsa -in server.key.orig -out server.key
 +Enter pass phrase for server.key.orig: #PASSWORD
 +writing RSA key
 +</sxh>
 +
 +Let's change the certificates permissions.
 +<sxh bash>
 +chmod 0400 /var/www/html/dqs-rails-base/config/ssl/
 +</sxh>
 +
 +Now let's create a backup of the nginx configuration
 +<sxh bash>
 +cp -Rfa /var/www/html/dqs-rails-base/config/nginx.conf{,.bkp}
 +</sxh>
 +
 +Now let's configure the nginx to use the ssl
 +<sxh nginx>
 +vim /var/www/html/dqs-rails-base/config/nginx.conf
 +# Puma configuration
 +upstream puma {
 +  server unix:///var/www/html/dqs-rails-base/shared/sockets/puma.sock;
 +}
 +
 +# Default server configuration
 +server {
 +  ## Sets the address and port for IP, or the path for a UNIX-domain socket on which the server will accept requests.
 +  listen 443;
 +  
 +  ## Sets names of a virtual server
 +  server_name rails.douglasqsantos.com.br;
 +  
 +  ## Enables or disables emitting nginx version in error messages and in the “Server” response header field.
 +  server_tokens off;
 +  
 +  ## Enables the HTTPS protocol for the given virtual server.
 +  ssl on;
 +  
 +  ## Specifies a file with the certificate in the PEM format for the given virtual server.
 +  # if you are using an valid certificate need to do the following process to use it.
 +  # cat server_name.crt CertCA.crt >> server.crt
 +  ssl_certificate /var/www/html/dqs-rails-base/config/ssl/server.crt;
 +  
 +  ## Specifies a file with the secret key in the PEM format for the given virtual server.
 +  ssl_certificate_key /var/www/html/dqs-rails-base/config/ssl/server.key;
 +
 +  ### Enable the timout of the ssl session to 5 minutes
 +  ssl_session_timeout  5m;
 +  
 +  ## Specifies the enabled protocols
 +  ssl_protocols  SSLv2 SSLv3 TLSv1;
 +  
 +  ## Specifies the enabled ciphers
 +  ssl_ciphers  HIGH:!aNULL:!MD5;
 +  
 +  ## Specifies the enabled ciphers
 +  ssl_prefer_server_ciphers   on;
 +
 +  ## Sets the root directory for requests
 +  root /var/www/html/dqs-rails-base/public;
 +  
 +  ## Logging
 +  access_log /var/www/html/dqs-rails-base/log/nginx.access.log;
 +  error_log /var/www/html/dqs-rails-base/log/nginx.error.log info;
 +
 +  ## Sets configuration for assets
 +  location ^~ /assets/ {
 +    gzip_static on;
 +    expires max;
 +    add_header Cache-Control public;
 +  }
 +
 +  try_files $uri/index.html $uri @puma;
 +  location @puma {
 +    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 +    proxy_set_header Host $http_host;
 +    proxy_set_header X-Forwarded-Proto https;
 +    proxy_redirect off;
 +    proxy_pass http://puma;
 +  }
 +
 +  error_page 500 502 503 504 /500.html;
 +  client_max_body_size 10M;
 +  keepalive_timeout 10;
 +}
 +</sxh>
 +
 +Now we need to restart the Nginx
 +<sxh bash>
 +systemctl restart nginx
 +</sxh>
 +
 +Now we need to restart the Puma
 +<sxh bash>
 +systemctl restart puma
 +</sxh>
 +
 +Now we can access https://ip_server or https://rails.douglasqsantos.com.br
 +
 +====== References ======
 +
 +  - http://nginx.org/
 +  - http://nginx.org/en/docs/ -> ** Modules reference**
 +  - http://nginx.com/resources/admin-guide/restricting-access/
 +  - http://nginx.com/resources/admin-guide/
 +  - http://wiki.nginx.org/NginxHttpCoreModule
 +  - http://wiki.nginx.org/Pitfalls
 +  - http://nginx.org/en/docs/http/ngx_http_core_module.html
 +  - http://wiki.nginx.org/Main
 +  - http://wiki.nginx.org/Install
 +  - http://wiki.nginx.org/Configuration
Print/export
QR Code
QR Code installing_and_configuring_nginx_with_puma_and_mysql_for_rails_on_debian_jessie_en (generated for current page)