#31 Production Deployment on Ubuntu

Summary

A guide to configure your Ubuntu installation and deploy a Ruby on Rails application. Lock down the settings to prevent unwanted access.
rails production security deployment 16:15

Summary

updates and add usersudo apt-get update && sudo apt-get upgrade -y
adduser deploy
sudo usermod -aG sudo deploy
sudo apt-get install curl nano git libmysqlclient-dev coffeescript gawk g++ gcc make libreadline6-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 autoconf libgmp-dev libgdbm-dev libncurses5-dev automake libtool bison pkg-config libffi-dev -y
login as deploy user, install applicationgpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
source /home/deploy/.rvm/scripts/rvm
rvm install 2.3.1
echo 'gem: --no-document' >> ~/.gemrc
gem update --system
gem install bundler
git config --global user.email 'YOUR_EMAIL'
git config --global user.name 'YOUR_NAME'
ssh-keygen -t rsa -C "YOUR_EMAIL"
cat ~/.ssh/id_rsa.pub
git clone [email protected]:driftingruby/sample_application.git
cd sample_application
bundle
echo 'export RAILS_ENV=production' >> ~/.bashrc
source ~/.bashrc
gem install passenger
install passenger dependenciessudo apt-get install apache2 libcurl4-openssl-dev apache2-dev libapr1-dev libaprutil1-dev
install mysql serversudo apt-get install mysql-server
configure application settingsnano config/database.yml
nano config/secrets.yml
install passenger apache modulesudo a2enmod headers
passenger-install-apache2-module
/etc/apache2/apache2.conf   LoadModule passenger_module /home/deploy/.rvm/gems/ruby-2.3.1/gems/passenger-5.0.28/buildout/apache2/mod_passenger.so
   <IfModule mod_passenger.c>
     PassengerRoot /home/deploy/.rvm/gems/ruby-2.3.1/gems/passenger-5.0.28
     PassengerDefaultRuby /home/deploy/.rvm/gems/ruby-2.3.1/wrappers/ruby
   </IfModule>
/etc/apache2/sites-enabled/000-default.confPassengerMaxPoolSize 4
  <VirtualHost *:80>
      Header add Strict-Transport-Security max-age=31536000
      DocumentRoot /home/deploy/sample_application/public
      <Directory /home/deploy/sample_application/public>
         Header unset ETag
         AllowOverride all
         Options -MultiViews
         Order allow,deny
         Allow from all
         Require all granted
      </Directory>
      PassengerMinInstances 2
  </VirtualHost>
If you need to create and configure self-signed certificatessudo mkdir /etc/apache2/ssl
cd /etc/apache2/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout apache.key -out apache.crt
sudo a2enmod ssl
enable apache module rewritesudo a2enmod rewrite
/etc/apache2/sites-enabled/000-default.conf# Redirects 80 traffic to 443 
<VirtualHost *:80>
    Redirect permanent "/" "https://107.170.118.82/"
</VirtualHost>

<VirtualHost *:443>
    Header add Strict-Transport-Security max-age=31536000
    DocumentRoot /home/deploy/sample_application/public
    <Directory /home/deploy/sample_application/public>
       Header unset ETag
       AllowOverride all
       Options -MultiViews
       Order allow,deny
       Allow from all
       Require all granted
    </Directory>
    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/apache.crt
    SSLCertificateKeyFile /etc/apache2/ssl/apache.key
    PassengerMinInstances 2
</VirtualHost>
restart apachesudo service apache2 restart
locking down sshsudo nano /etc/ssh/sshd_config
sudo su
sudo mv /root/.ssh/authorized_keys ~/.ssh/
sudo chown -R deploy ~/.ssh/authorized_keys
sudo service ssh restart
installing and configuring ufwsudo apt-get install ufw
sudo ufw status
sudo ufw allow 22222/tcp
sudo ufw allow www/tcp
sudo uff allow 443/tcp
sudo ufw enable
Kiran Patil said 11 months ago:

Hi,


Please add nginx with puma configuration for production.


Thanks.

kobaltz PRO said 11 months ago:

This is the config that I use for nginx/puma. The puma.rb is within the rails application's config folder.

nginx.conf

upstream backend {
  server unix:///var/run/puma/my_app.sock;
}
server {
  listen 80;
  server_name _ localhost;
  access_log /var/log/nginx/access.log main;
  error_log /var/log/nginx/error.log;
  large_client_header_buffers 8 32k;
  root /var/app/current/public;
  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_set_header X-NginX-Proxy true;
    proxy_buffers 8 32k;
    proxy_buffer_size 64k;
    proxy_pass http://backend;
    proxy_redirect off;
    # enables WS support
    location /cable {
      proxy_pass http://backend;
      proxy_http_version 1.1;
      proxy_set_header Upgrade "websocket";
      proxy_set_header Connection "Upgrade";
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
  }
  
  location /assets {
    alias /var/app/current/public/assets;
    gzip_static on;
    gzip on;
    expires max;
    add_header Cache-Control public;
  }
  location /public {
    alias /var/app/current/public;
    gzip_static on;
    gzip on;
    expires max;
    add_header Cache-Control public;
  }
}

config/puma.rb

threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
threads 2, threads_count
port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
preload_app!
before_fork do
  ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord)
end
on_worker_boot do
  ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
end
plugin :tmp_restart


Kiran Patil said 11 months ago:

Thanks, one more thing is don't we need daemonize to run puma in background and environment is pointing to "development" in pumb.rb but it should be "production".

Kiran Patil said 10 months ago:

Hi,

Have you used capistrano for app deployment ?

Please throw some light on it.

Thanks.

Kiran Patil said 10 months ago:

What would be configuration/tuning for postgresql on production ?

kobaltz PRO said 10 months ago:

I don't do too much with PostgreSQL, but is there specific cases that you're looking for?

Kiran Patil said 10 months ago:

No, I am looking for generic configuration tuning for on-premise server.

amarillo11 said 4 months ago:

Any reasoning on rvm over rbenv?

kobaltz PRO said 4 months ago:

it is a personal preference. Ive been using it for years without problems so I have not had a reason to change.

Login to Comment