Run Two Different Rails Application on One Dedicated Server

Run two different Rails application on one dedicated server

I will describe how I run multiple Rails applications on one Linux server, using Apache, Phusion Passenger, and some version of Ruby. You have many choices, but this should help you get started. Many of these details come from the installation script

First, install Phusion Passenger.

> gem install passenger

Second, build the Apache 2 Passenger module. You should be able to execute the following script installed during step one.

> passenger-install-apache2-module

This script will compile the Apache 2 module and explain how to configure Apache. If dependencies are missing the script should offer some helpful advice about how to install them.

Third, edit your Apache configuration file. I have to add something like this. (Just use this for references and don't worry about .rvm) The script run in step two will give you something that you can copy and paste.

LoadModule passenger_module /Users/me/.rvm/gems/ree/gems/passenger-3.0.9/ext/apache2/mod_passenger.so
PassengerRoot /Users/me/.rvm/gems/ree/gems/passenger-3.0.9
PassengerRuby /Users/me/.rvm/wrappers/ree/ruby

Fourth, add something like this to your Apache configuration file for each application you want to run.

<VirtualHost *:80>
ServerName app1.example.com
DocumentRoot /somewhere/app1/public # <-- be sure to point to 'public'!
<Directory /somewhere/app1/public>
AllowOverride all # <-- relax Apache security settings
Options -MultiViews # <-- MultiViews must be turned off
</Directory>
</VirtualHost>

If you have two Rails application sharing one database then they will both have similar connection information in config/database.yml

How should I build a VPS that will host multiple small Rails applications?

I would recommend using Apache + Passenger. Passenger by default loads the application only when you need it, e.g. the first request will take a bit longer (actually as long as it takes to load your framework).

If the application is idle for some predefined time, it will be removed from memory.

Setup is very easy and adding new applications is just adding one line in your apache configuration.

Running two puma servers at once for the same rails project, force kills one of the servers?

You need to comment plugin :tmp_restart in config/puma.rb.

This is source code of this plugin: https://github.com/puma/puma/blob/master/lib/puma/plugin/tmp_restart.rb

Rails app with multiple subdomains on separate machines

There are two very different goals intertwined here:

One is distributing the load over multiples machines. You don't need to break out your application into multiple apps for that. You could use a load balancer for this (incoming requests are spread across multiple machines running the same app), or split your app up.

The other is more about the logical architecture of your app. In general the bigger an app is, the more complicated it is and it's easier to work on simple apps. Therefore you might want to split your app up into smaller apps. This is orthogonal to the hardware issue - you could choose to split your app up threeways but still run them on the same machine (it does of course give you the flexibility to allocate resources differently to your app)

Coming back to you question, one aspect worth exploring is should there be any shared models? To what extent can (for example) your dashboard query your api (possibly private apis) rather than querying the database directly? Splitting up your application into multiple services makes some things easier, some things harder, but it does help you keep individual applications smaller and keep the boundaries between them clean without any hidden dependencies. This logical split doesn't have to correspond the the physical layout: one server may host several applications

Lastly the most direct answer to your question is to write a rails engine. An engine can contain pretty much anything an app can (applications are special cases of engines), for example models, views, controllers routes etc. You'd create one with your common code, package this up as a gem (doesn't have to be a public one) and add it each app's Gemfile.

Nginx for two Rails applications - root and special subfolder

Yes. Just follow the sub-URI deployment instructions in the Phusion Passenger Nginx manual: https://www.phusionpassenger.com/library/deploy/nginx/deploy/ruby/#deploying-an-app-to-a-sub-uri-or-subdirectory

(Using phusion passenger + Nginx) running same rails app with multiple instance names with same port (80)

Here is a sample example of a minimal server block for nginx + passenger

server {
listen 80;
server_name client1.foobar.com;
root /var/www/rails/client1/current/public;

passenger_enabled on;
}

The usual way of configuring nginx is to make a subdirectory "sites-available" where you put a file named "client1.foobar.com" containing this snippet , then make a symbolic link for this file in another subdirectory named "sites-enabled". Finally you add the following line in you nginx.conf inside the http block

include /path/to/your/sites-enabled/*;

Do not forget to reload/restart your nginx.

This way of using symbolic link allows you to easily disable any site you want by deleting the symbolic link without losing your config file.

You can find some example and more documentation here : http://www.modrails.com/documentation/Users%20guide%20Nginx.html

How to deploy a Rails app to a VPS (or dedicated server)?

I have successfully deployed a heavy Rails application to Linode or Digital Ocean, using these technologies:

  • rbenv for Ruby installation
  • nginx + Passenger for the application server
  • PostgreSQL for the database server
  • Capistrano to automate deploys (configure this first on your dev machine with your server IP and settings, I will not cover it here)

These are the steps that work for me:

Setting up the virtual machine

Create a new virtual machine

Follow the setup instructions of your hosting, being Linode or Digital Ocean, to create the node and set it up.

Set up date

  • dpkg-reconfigure tzdata

Update packages

  • apt-get update
  • apt-get upgrade

Security

Create user

  • adduser deploy
  • usermod -a -G sudo deploy
  • logout

Set up SSH key-authentication

On local:

  • ssh-keygen
  • copy the public key:

    • scp ~/.ssh/id_rsa.pub deploy@example.com:~

On the server:

  • ssh deploy@example.com
  • enable the alias to list files:

    • vim ~/.bashrc
    • uncomment all aliases
  • mkdir .ssh
  • mv id_rsa.pub .ssh/authorized_keys
  • chown -R deploy:deploy .ssh
  • chmod 700 .ssh
  • chmod 600 .ssh/authorized_keys
  • logout (test the new authentication)

Set up SSH

  • sudo vim /etc/ssh/sshd_config
  • Switch PermitRootLogin to no
  • sudo service ssh restart

Set up firewall

  • sudo iptables -L (it should show a void table)
  • sudo vim /etc/iptables.firewall.rules
  • Paste this: https://gist.github.com/davidmles/89fc88e48e17cf8252bfca374e46355f#file-iptables-firewall-rules
  • sudo iptables-restore < /etc/iptables.firewall.rules
  • sudo iptables -L (now it should show the configured rules)
  • sudo vim /etc/network/if-pre-up.d/firewall
  • Paste this: https://gist.github.com/davidmles/89fc88e48e17cf8252bfca374e46355f#file-firewall
  • sudo chmod +x /etc/network/if-pre-up.d/firewall

Set up fail2ban

Set up if you have enough free memory, as it tends to eat it.

  • sudo apt-get install -y fail2ban

Setup Ruby

Install Git

  • sudo apt-get install -y git

Install rbenv

  • git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
  • echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
  • echo 'eval "$(rbenv init -)"' >> ~/.bashrc
  • source ~/.bashrc
  • git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

Install Ruby

  • sudo apt-get install -y curl gnupg build-essential
  • rbenv install -l (look for the latest version)
  • rbenv install 2.3.3 (or the latest available version at this moment)
  • rbenv global 2.3.3
  • rbenv rehash
  • vim .gemrc

    • Paste this: gem: --no-document

Setup servers

Install nginx + Passenger

  • Install following the documentation:

    • https://www.phusionpassenger.com/library/install/nginx/install/oss/jessie/

Install PostgreSQL

  • Install following the documentation:

    • https://wiki.postgresql.org/wiki/Apt#PostgreSQL_packages_for_Debian_and_Ubuntu

Setup libraries

Install node.js

Needed to pre-compile assets.

  • sudo apt-get install -y nodejs

Install bundler

  • get install bundler
  • rbenv rehash

Setup the application

Create the user in PostgreSQL

  • createuser username --pwprompt
  • createdb -Ousername -Eutf8 db_name
  • Test it:

    • psql db_name --user username --password

Deploy the code
* On the server:
* sudo mkdir -p /srv/yoursite.com
* sudo chown deploy:deploy /srv/yoursite.com
* On your dev machine:
* bundle exec cap production deploy:check (it will throw an error because it doesn't find the database)
* On the server:
* cd /srv/yoursite.com/shared/config
* vim database.yml (paste your database config)
* vim secrets.yml (paste your secrets config)
* On your dev machine:
* bundle exec cap production deploy
* bundle exec cap production whenever:update_crontab

Configure logrotate

  • Follow this guide: * https://gorails.com/guides/rotating-rails-production-logs-with-logrotate

Is it possible to run multiple mongodb processes/servers/ports on one physical server?

Yes.

mongod --dbpath /path/to/my/production/rails/app/db --port 12345
mongod --dbpath /path/to/my/staging/rails/app/db --port 12346

Check out this earlier answer for more information/pitfalls: multiple instances of Mongo DB on same server



Related Topics



Leave a reply



Submit