Para evitar entrar como usuario root, crear otro usuario y darle permisos de sudo
$ sudo adduser deploy$ sudo gpasswd -a deploy sudoGenerarla en la máquina local
local$ ssh-keygen
local$ cat ~/.ssh/id_rsa.pubPegarla en el servidor, dentro de authorized_keys
$ su - deploy
$ mkdir .ssh
$ chmod 700 .ssh
$ nano .ssh/authorized_keysLuego dar permisos nuevamente
$ chmod 600 .ssh/authorized_keysEntrar a la cuenta root
# nano /etc/ssh/sshd_config
PermitRootLogin yes -> noReiniciar el servicio SSH
$ sudo service ssh restartSalir del servidor e intentar entrar nuevamente para probar que el acceso root quedó deshabilitado.
Correr comandos sudo sin la clave
$ sudo visudo
#Pegar al final de todo
deploy ALL=(ALL) NOPASSWD:ALLTimezone
$ sudo dpkg-reconfigure tzdataNTP
$ sudo apt-get update
$ sudo apt-get install ntpComprobar si existe swap
$ free -hVerificar cuanto espacio disponemos de Disco
$ df -hAgregar 1G de memoria SWAP
$ sudo fallocate -l 1G /swapfileVerificar
$ ls -lh /swapfileHabilitar espacio SWAP
$ sudo chmod 600 /swapfileVerificar los permisos:
$ ls -lh /swapfileMarcar el espacio como espacio swap
$ sudo mkswap /swapfile
$ sudo swapon /swapfile
$ sudo swapon --show
$ free -hMake the Swap File Permanent
$ sudo cp /etc/fstab /etc/fstab.bak
$ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstabTweak your Swap Settings
$ cat /proc/sys/vm/swappiness
Output
60For a Desktop, a swappiness setting of 60 is not a bad value. For a server, you might want to move it closer to 0.
We can set the swappiness to a different value by using the sysctl command. For instance, to set the swappiness to 10, we could type:
$ sudo sysctl vm.swappiness=10This setting will persist until the next reboot. We can set this value automatically at restart by adding the line to our /etc/sysctl.conf file:
$ sudo nano /etc/sysctl.confAt the bottom, you can add:
vm.swappiness=10$ cat /proc/sys/vm/vfs_cache_pressure
Output
100As it is currently configured, our system removes inode information from the cache too quickly. We can set this to a more conservative setting like 50 by typing:
sudo sysctl vm.vfs_cache_pressure=50
Output
vm.vfs_cache_pressure = 50Again, this is only valid for our current session. We can change that by adding it to our configuration file like we did with our swappiness setting:
$ sudo nano /etc/sysctl.confAt the bottom, add the line that specifies your new value
vm.vfs_cache_pressure=50Agregar dependencias
sudo apt update
sudo apt -y install curl dirmngr apt-transport-https lsb-release ca-certificates
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -Instalar node en su versión 12
sudo apt -y install nodejsInstalar algunas dependencias base
$ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
$ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
$ sudo apt-get update
$ sudo apt-get install git-core zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev software-properties-common libffi-dev yarnInstalar gnupg2
sudo apt install gnupg2Instalar RVM y Ruby
$ cd /tmp
$ sudo apt-get install libgdbm-dev libncurses5-dev automake libtool bison libffi-dev
$ curl -sSL https://rvm.io/mpapis.asc | gpg2 --import -
$ curl -sSL https://rvm.io/pkuczynski.asc | gpg2 --import -
$ curl -sSL https://get.rvm.io | bash -s stable
$ source ~/.rvm/scripts/rvm
$ rvm install x.x.x
$ rvm use x.x.x --default
$ ruby -v$ gem install rails -v x.x.x --no-documentInstalar Bundler:
$ gem install bundler$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"$ ssh-keygen
$ cat /home/deploy/.ssh/id_rsa.pub
$ ssh -T [email protected]
$ ssh -T [email protected]$ sudo apt install postgresql libpq-devCrear el usuario deploy y la base de datos para la aplicación
$ sudo su - postgres
$ createuser --pwprompt deploy # preguntará por password, será la password para acceder a la base de datos
$ createdb -O deploy database_app_name # nombre de la base de datos de la app
$ exitOJO, los datos ingresados anteriormente, son lo que van en el archivo database.yml más adelante
Instalar nginx
sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx
Lo dejamos así por mientras, ya que primero debemos hacer el deploy, y nginx lo configuramos al final
Agregar las gemas de capistrano necesarias al Gemfile
group :development do
gem 'capistrano', require: false
gem 'capistrano-rails', require: false
gem 'capistrano-bundler', require: false
gem 'capistrano-puma', require: false
gem 'capistrano-ssh-doctor', require: false
gem 'capistrano-rbenv', require: false
end
Agregar las dependencias necesarias
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main > /etc/apt/sources.list.d/passenger.list'
echo "deb https://oss-binaries.phusionpassenger.com/apt/passenger focal main" | sudo tee /etc/apt/sources.list.d/passenger.list
sudo apt-get updateInstala Passenger y Nginx
$ sudo apt-get install -y nginx-extras libnginx-mod-http-passengerCrea un symlink al modulo de passenger en Nginx:
$ if [ ! -f /etc/nginx/modules-enabled/50-mod-http-passenger.conf ]; then sudo ln -s /usr/share/nginx/modules-available/mod-http-passenger.load /etc/nginx/modules-enabled/50-mod-http-passenger.conf ; fi
$ sudo ls /etc/nginx/conf.d/mod-http-passenger.confAhora necesitamos que passenger apunte a la correcta version de ruby.
Editamos el siguiente archivo:
$ sudo nano /etc/nginx/conf.d/mod-http-passenger.confY modificamos sólo la líne que dice passenger_ruby por
passenger_ruby /home/deploy/.rvm/rubies/ruby-2.4.2/bin/ruby; # modificar por la version que correspondaIniciamos el servicio de nginx
sudo service nginx startNext we're going to remove this default NGINX server and add one for our application instead.
$ sudo rm /etc/nginx/sites-enabled/default
$ sudo nano /etc/nginx/sites-enabled/nombre_app
``` console
Y pegar la siguiente configuración
``` console
server {
listen 80;
listen [::]:80;
server_name IP_SERVER;
root /home/deploy/app_folder_name/current/public;
passenger_enabled on;
passenger_app_env production;
# Allow uploads up to 100MB in size
client_max_body_size 100m;
location ~ ^/(assets|packs) {
expires max;
gzip_static on;
}
}Reniciar servicio de nginx
$ sudo service nginx reloadAgregar Capistrano al Gemfile
group :development do
gem 'capistrano', require: false
gem 'capistrano-rvm', require: false
gem 'capistrano-rails', require: false
gem 'capistrano-bundler', require: false
gem 'capistrano-passenger', require: false
gem 'capistrano-ssh-doctor', require: false
gem 'capistrano-rails-collection'
endInstalar gemas
$ bundle install
$ cap install# Load DSL and set up stages
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rvm'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/passenger'
require 'capistrano/ssh_doctor'
require 'capistrano/rails/collection'
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }set :repo_url, 'REPO_URL.git'
set :application, 'APP_NAME'
set :user, 'deploy'
# Don't change these unless you know what you're doing
set :pty, true
set :use_sudo, false
set :stage, :production
set :deploy_via, :remote_cache
set :deploy_to, "/home/#{fetch(:user)}/#{fetch(:application)}"
set :ssh_options, { forward_agent: true, user: fetch(:user), keys: %w(~/.ssh/id_rsa) }
set :linked_files, fetch(:linked_files, []).push('.env', 'config/database.yml', 'config/secrets.yml')
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')
set :keep_releases, 5
namespace :deploy do
# Not needed if using capistrano-passenger gem/recipe
# desc 'Restart application'
# task :restart do
# on roles(:app), in: :sequence, wait: 5 do
# execute :touch, release_path.join('tmp/restart.txt')
# end
# end
after :publishing, 'deploy:restart'
after :finishing, 'deploy:cleanup'
endEn el archivo config/deploy/production.rb llenar con los datos de la IP y el usuario del servidor (deploy en este caso).
server 'IP.DEL.SERVIDOR', user: 'deploy', roles: %w{web db app}Iniciar el primer deploy
$ cap production deployLo cual fallará, porque no encontrará los linked_files, para eso debemos entrar al servidor y crearlos (en carpeta del proyecto, dentro del servidor)
- Crear archivo .env
- Crear archivo database.yml en carpeta shared/config
- Crear archivo secrets.yml en carpeta shared/config
Una vez creados, y llenados con sus respectivos datos volver a intentar el deploy
$ cap production deployInstalar Nginx solito
$ sudo apt-get install nginx -yInstalar Puma en el servidor
$ gem install puma -v 3.7.0Agregar Puma y Mina al Gemfile
gem 'puma', '3.7'
gem 'mina', require: false
gem 'mina-puma', require: false, github: 'untitledkingdom/mina-puma'Instalar gemas
$ bundle install
$ mina initEsto generará el archivo config/deploy.rb y deberá quedar mas o menos así
require 'mina/rails'
require 'mina/git'
require 'mina/rvm'
require 'mina/puma'
set :user, 'deploy'
set :application_name, 'nombre_carpeta_proyecto'
set :domain, 'IP.DEL.SERVIDOR'
set :deploy_to, '/home/deploy/nombre_carpeta_proyecto'
set :repository, '[email protected]:repo-git-url'
set :branch, 'master'
set :shared_dirs, fetch(:shared_dirs, []).push('log', 'tmp/pids', 'tmp/sockets')
set :shared_files, fetch(:shared_files, []).push(
'.env',
'config/database.yml',
'config/secrets.yml',
'tmp',
'log',
'config/puma.rb'
)
task :remote_environment do
invoke :'rvm:use', '2.3.1'
end
task :setup do
command %[touch "#{fetch(:shared_path)}/config/database.yml"]
command %[touch "#{fetch(:shared_path)}/config/secrets.yml"]
comment "Be sure to edit '#{fetch(:shared_path)}/config/database.yml', 'secrets.yml' and puma.rb."
end
task :setup do
command %[mkdir -p "/home/deploy/nombre_carpeta_proyecto/shared/log"]
command %[chmod g+rx,u+rwx "/home/deploy/nombre_carpeta_proyecto/shared/log"]
command %[mkdir -p "/home/deploy/nombre_carpeta_proyecto/shared/config"]
command %[chmod g+rx,u+rwx "/home/deploy/nombre_carpeta_proyecto/shared/config"]
command %[mkdir -p "/home/deploy/nombre_carpeta_proyecto/shared/tmp"]
command %[chmod g+rx,u+rwx "/home/deploy/nombre_carpeta_proyecto/shared/tmp"]
command %[touch "/home/deploy/nombre_carpeta_proyecto/shared/.env"]
command %[touch "/home/deploy/nombre_carpeta_proyecto/shared/config/database.yml"]
command %[touch "/home/deploy/nombre_carpeta_proyecto/shared/config/secrets.yml"]
command %[touch "/home/deploy/nombre_carpeta_proyecto/shared/config/puma.rb"]
end
desc "Deploys the current version to the server."
task :deploy do
deploy do
comment "Deploying #{fetch(:application_name)} to #{fetch(:domain)}:#{fetch(:deploy_to)}"
invoke :'git:clone'
invoke :'deploy:link_shared_paths'
invoke :'bundle:install'
invoke :'rails:db_migrate'
invoke :'rails:assets_precompile'
invoke :'deploy:cleanup'
on :launch do
invoke :'puma:phased_restart'
end
end
# you can use `run :local` to run tasks on local machine before of after the deploy scripts
run(:local){ say 'done' }
endInicializar Mina desde la máquina local
$ mina setupBy default, Mina will create all folders mentioned in shared_dirs and shared_files. In setup, however, you can add section auto-creation of empty files and fill them later.
Después de esto, hay que entrar al servidor y llenar los datos necesarios en los archivos
- .env
- puma.rb
- database.yml
- secrets.yml
Llenar el archivo puma.rb
environment "production"
bind "unix:/home/deploy/nombre_carpeta_proyecto/shared/tmp/sockets/puma.sock"
pidfile "/home/deploy/nombre_carpeta_proyecto/shared/tmp/pids/puma.pid"
state_path "/home/deploy/nombre_carpeta_proyecto/shared/tmp/sockets/puma.state"
directory "/home/deploy/nombre_carpeta_proyecto/current"
workers 2
threads 1,4
daemonize true
stdout_redirect "/home/deploy/nombre_carpeta_proyecto/shared/log/puma.stdout.log", "/home/deploy/nombre_carpeta_proyecto/shared/log/puma.stderr.log"
activate_control_app 'unix:/home/deploy/nombre_carpeta_proyecto/shared/tmp/sockets/pumactl.sock'
prune_bundlerEliminamos la configuración default.
$ sudo rm /etc/nginx/sites-enabled/defaultAhora creamos la nueva configuación en:
$ sudo nano /etc/nginx/sites-available/nombre_appModificar archivo /etc/nginx/sites-available/nombre_app con lo siguiente, y reemplazar donde corresponda
upstream puma {
server unix:///home/deploy/APP_FOLDER/shared/tmp/sockets/APP_NAME-puma.sock;
}
server {
listen 80;
listen [::]:80;
server_name IP.DEL.SERVIDOR;
root /home/deploy/APP_FOLDER/current/public;
access_log /home/deploy/APP_FOLDER/current/log/nginx.access.log;
error_log /home/deploy/APP_FOLDER/current/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;
}