PLEASE view this file in PLAINTEXT, as I do not know how to use rdoc.
To get this app running, first run the migrations with “rake db:migrate” and then try out “rails server” to see that it works with WEBrick.
If so, then you can install apache and also phusion passenger (aka “passenger”).
First, after installing apache and passenger, make sure it works at all by doing
$ sudo apachectl restart
and putting in the URL (or IP ADDRESS) of your remote server.
Now, to get my Rails app served with Apache/Passenger installation on Centos 7, I needed to do the following:
-
Comment out all lines in “/etc/httpd/conf.d/welcome.conf” to get rid of the default welcome page.
-
Create the file “etc/httpd/conf.d/passenger.conf”, and add the following lines to it:
LoadModule passenger_module /home/l/.rvm/gems/ruby-2.0.0-p576/gems/passenger-4.0.53/buildout/apache2/mod_passenger.so <IfModule mod_passenger.c> PassengerRoot /home/l/.rvm/gems/ruby-2.0.0-p576/gems/passenger-4.0.53 PassengerDefaultRuby /home/l/.rvm/gems/ruby-2.0.0-p576/wrappers/ruby </IfModule>
(The exact nature of this is dependent on your particular passenger installation; I got this by running the command “passenger-install-apache2-module”).
-
Create the file “/etc/httpd/conf.d/virtualhost.conf”, and add the following lines to it:
RackEnv production <VirtualHost *:80> ServerName depot.myhostislinode.com # !!! Be sure to point DocumentRoot to 'public'! DocumentRoot /var/www/html/depot/public <Directory /var/www/html/depot/public> # This relaxes Apache security settings. AllowOverride all # MultiViews must be turned off. Options -MultiViews # Uncomment this if you're on Apache >= 2.4: #Require all granted </Directory> </VirtualHost>
Notice that we use “RackEnv production” here. If you just want to test that everything works in your deployment server as your development environment on your development machine, change this to “RackEnv development”.
-
As Apache by default points to /var/www/html, I needed to symlink my Rails app’s root folder, like this:
$ cd /var/www/html $ ln -s /home/l/some/path/to/my/app/named/depot
-
You have to enable the $SECRET_KEY_BASE environment variable, as Rails 4 production mode requires this by default (see “depot/config/secrets.yml”. The UNIX way to do this, without touching your application, is to figure out which shell you are using.
$ echo $SHELL
For my remote server, I log in as a normal user, and for that user I log in with “/bin/zsh”. Because zsh sources ~/.zprofile, I needed to export the $SECRET_KEY_BASE variable in ~/.zprofile. If you do not use zsh, google and find out which file is sourced by your shell (I believe bash sources ~/.bash_profile. So, the trick is to first generate a secret key, and enable it in a shell profile file, as follows:
$ cd path/to/depot $ RAILS_ENV=production rake secret
This will generate a long secret hex number (our secret key). To enable it, put this in your ~/.zprofile:
$ export SECRET_KEY_BASE=your_long_secret_hex_number
and then restart apache.
To add books, you have to first create a new administrative user. You can do this with the rails console: “User.create(name: ‘yourname’, password: ‘yourpassword’, password_confirmation: ‘yourpassword’)”. Make sure to run “rails console” with “RAILS_ENV=production”, as you will be using the production environment, like this:
$ RAILS_ENV=production rails console <ruby_version> :001> User.create(name: 'yourname', password: 'yourpassword', password_confirmation: 'yourpassword')
To use Postgresql (PG) for the database, I needed to do:
-
Install postgresql (and also postgresql-server)
-
Enable/start postgresql with ‘sudo systemctl enable postgresql.service’ and also ‘sudo systemctl start postgresql.service’.
-
Create a PG user, with
$ sudo -u postgres psql postgres=# \du postgres=# create role depot_role login createdb; postgres=# \du postgres=# \q
-
Modify my database.yml file to be like this:
default: &default adapter: postgresql encoding: unicode pool: 5 development: <<: *default user: depot_role database: depot_development # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: <<: *default user: depot_role database: depot_test production: <<: *default user: depot_role database: depot_production
(Notice how in ‘user: depot_role’, we give the name of the PG role that we created).
-
Set up the db (and apply all migrations) with ‘rake db:setup RAILS_ENV=production’.
You might be wondering why we didn’t use the ‘postgres’ role that comes pre-installed by default with Centos’s “postgresql” (or is it “postgresql-server”?) package. The reason is because that user has superuser privileges within PG, and our depot app certainly does not need such high level privileges. This is basically a security issue (I am assuming that doing this prevents our exploited/rogue app from doing damage to other data stored in PG in our server — which is important if we’re running, for example, multiple webapps with multiple databases all in the same PG instance).
If the ‘rake db:setup’ command fails b/c of peer authentication failure like this:
PG::ConnectionBad: FATAL: Peer authentication failed for user "depot_role"
, this means that PG is trying to authenticate the user “depot_role” based on the operating system’s logged-in username. If your system’s username is different than “depot_role” that you created in PG, you will get this failure if you enable peer authentication in your pg_hba.conf file. You can find the location of the pg_hba.conf file by doing “SHOW hba_file;” in the PG console.
So, to fix this issue, you need to edit the “pg_ident.conf” file (you can find the location with “SHOW ident_file;” in PG). Put the following in “pg_ident.conf”:
rails your-os-username depot_role rails your-os-username postgres
. Then, you need to turn on this mapping for peer authentication (which is enabled by default for local connections in the default postgresql install on Centos) by editing “pg_hba.conf” from
# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all peer
to
# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all peer map=rails
. If you have “trust” as the method instead of “peer”, then you don’t need to do any of this, as PG will assume anyone who can connect to the server is authorized to access the database with whatever name they specify.
Personally, I like this method as it avoids putting in your chosen PG role’s password as cleartext in your database.yml file (which is required if you use the “md5” method instead of “peer”).
To test that you can indeed use peer authentication, do
$ psql --username postgres
and see if you can connect to the PG server. This is slightly different than what most people on the web recommend, which is “sudo -u postgres psql”. After loggin in as the “postgres” PG username, check to see that the “depot_role” role exists with the “\du” command. If it doesn’t create it with “create role depot_role with createdb login;”.
-
Missing assets
To enable CSS/JS in Rails 4 production mode, you have to enable “config.assets.compile = true” (off by default) in “config/environments/production.rb”.
If your images are not working, make sure to delete the depot/tmp folder entirely and try again.
I followed this page www.linode.com/docs/security/securing-your-server and used iptables to block spurious traffic.