3. Setup the Web Server Manually
Now we have a fully working, modern ruby setup. We just don’t have a web server, rails or a database up. Let’s remedy the first two by using passenger.
Passenger is an application server. You need to use it to allow Nginx to communicate with the Rails app (like mod_php). Otherwise you would need to use the almost obselete cgi (Common Gateway Interface implemented in Nginx) to communicate. For this book I chose Passenger because it’s easier for newcomers to understand and get started. Unicorn is an alternate application server that offers 100% uptime. However there are drawbacks. Unicorn takes alot more memory and it can only host one Rails app per instance. Stick with Passenger for now to get confortable and you can switch to Unicorn in the future.
Install passenger with our newly setup rubygems
gem install passenger --no-ri --no-rdoc
Now this is the fun part. With RVM and passenger you can automate the installation and (most of the) configuration of nginx.
rvmsudo passenger-install-nginx-module
Too bad it fails on stock Ubuntu 12.04. It will tell you to use 3 different terminal commands to install the necessary packages. I have condensed them for your convenience.
sudo apt-get install build-essential libcurl4-openssl-dev zlib1g-dev -y
rvmsudo passenger-install-nginx-module
Choose option 1. Hit enter for the default directory.
Now start nginx because it will not start on its own.
sudo service nginx start
Now it will give another error. Passenger nginx doesn’t come with the nice Debian/Ubuntu scripts. Let’s remedy that.
wget -O init-deb.sh http://library.linode.com/assets/660-init-deb.sh
sudo mv init-deb.sh /etc/init.d/nginx
sudo chmod +x /etc/init.d/nginx
sudo /usr/sbin/update-rc.d -f nginx defaults
Now any of these 3 commands will work. Use nginx start.
sudo /etc/init.d/nginx stop
sudo /etc/init.d/nginx start
sudo /etc/init.d/nginx restart
Type your remote vps’s ip address into the broswer url to see your new server’s index page.
You now have a functioning webserver. You now just need to configure it and upload your rails app.
Let’s open the nginx configration.
sudo nano /opt/nginx/conf/nginx.conf
There should be a server bracket. Change the text inside to this.
server {
listen 80;
server_name example.com;
passenger_enabled on;
root /var/www/your_rails_app/public;
}
Nginx should now give you an error when you visit your ip address.
Nginx also gives it’s version number which is really bad. An attacker could look up exploits for your version of nginx with this info. Let’s fix that.
Before the server add this line like so.
server_tokens off;
server {
listen 80;
server_name example.com;
passenger_enabled on;
root /var/www/your_rails_app/public;
}
Restart the server
sudo /etc/init.d/nginx restart
Check again to see the version number was removed.
Now let’s finally get passenger and your rails app working.
You need to install a web server within rails to run the app.
sudo apt-get install nodejs
Create the directory.
sudo mkdir /var/www
Now for laughs and giggles create a new rails app on the vps.
rails new your_rails_app
Add some scaffolding.
rails g scaffold sales
Copy it over to /var/www
cp -r your_rails_app /var/www/
Go to your server’s public page to see your app in production (it won’t work yet, but we will get to that).
But what if you want to copy over your own local version to the vps? Like a real developer? We use rsync to accomplish that.
Rsync is a tool intended to automate file uploading. It’s used all the time in backups and other server admin tasks. Let’s use it to upload the local rails project.
Make sure to exit the vps’s ssh.
Now rsync your app to the vps.
rsync -avz -e ssh your_rails_app user@148.211.114.67:/var/www/
sudo chmod -R 755 your_rails_app
sudo chown -R 755 your_rails_app
sudo chown -R user your_rails_app
Now ssh back into the vps and cd into /var/www
cd your_rails_app
Run the bundler.
bundle install
Try visiting a dynamic part of your website (or /sales of the one created). You should get an error. But what could it be? You can check log/production.log in your rails app to find out.
If you get a table error make sure you didn’t forget to migrate the db (for production):
rake db:migrate RAILS_ENV="production"
If you see an assets error you need to run a command to compile them.
rake assets:precompile
If you’re wondering, yes, you need to rerun the assets command everytime you upload a new version (specifically whenever you change javascript, css or other assets). Thankfully, we can automate this as told in the automation chapter.
Your website should be working by now.