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
Namespaced Models in Rails: What's the State of the Union
How to Force Activerecord to Reload a Class
Capistrano & Bash: Ignore Command Exit Status
How to Set a Blank Value for an F.Select Form Field
What's the Variable Scope Within 'Class_Eval' String
How to Remove/Disable Sign Up from Devise
Rails Scope Find with Current User
Error Message "Xcode Alone Is Not Sufficient on Sierra"
How to Export a Ruby Array from My Heroku Console into CSV
What's the Difference Between Controllers and Actions in Ruby on Rails
Rails Console Running Incredibly Slowly When Editing Text
Rails - How to Check Developer Mode or Production Mode in Code
Ruby Koan 151 Raising Exceptions
How to Send Mail with Rails Without a Template
Creating Categories on Jekyll Driven Site
Simple_Form: Remove Outer Label for an Inline Checkbox with Label