Setup VPS (Bluehost) to deploy and update RoR apps (Heroku Style) - ruby-on-rails

My goal is to setup my environment to be able to run $ git push myapp master on my local computer AND automatically deploy/update my RoR app on my VPS at Bluehost.
On my computer (Linux-Ubuntu) the RoR app is at: /var/www/myapp
I followed this GREAT explained tutorial and I have a plenty functional git installation on my VPS server at ~/git/repository/myapp
Ideally, my deployed RoR app will be located on Bluehost at ~/rails_apps/myapp
Bluehost automatically uses Pushion Passenger, and there is a symlink between ~/public_html/myapp folder and the public side of the RoR app, located at ~/rails_apps/myapp/public.
I am stuck with the post-receive git hook and I am not using Capistrano (should I?)
I have been reading many documents with similar goals, like this one, or this other one, I even found this gem.
There are different ways to achieve same goal and I am still confused because I have not found a post-receive hook example that fits my need (and have not grasp the logic).
I have been on git guides specific section for hooks and it tells what you can do but not how to do it, which is great for everyone but a rookie.
Any help with the scenario and the goal? Will it be easier if I use Capistrano and/or git-rails gem? Other suggestions?
THANKS.
ADDITION:
Hi, I am using Capistano now but have not acheved the goal yet.
I have my app at /var/www/my_app on linux local machine.
The git repository remote --bare and --share is at user#myserver:/server/user/git/repository/my_app.
I want to deploy to /server/user/rails_apps/my_app.
At deploy.rb I have
set:application, "my_app".
set :respository, "user#myserver:/server/git/repository/my_app.
set:user, "my_user_name".
set: domain, "mysite.com".
set :scm, :git.
set_scm_command, "/server/user/bin/git".
set :scm_passphrase, "my_phrase".
set :deploy_to, "/server/user/rails_apps/my_app".
set :deploy_via, :remote_cache.
set :tmp_dir, "/server/user/tmp".
When I run it, tels me: fatal: No remote configured to list refs from.
Can you give me some guidance? Thanks.

Yes, The standard way is Capistrano or Mina and provisioning a rails environment in a hosted directory. If you are hell bent on doing it the heroku way you can use Vagrant to provision your own heroku environment here: https://github.com/openruko/vagrant-openruko

Related

Setting up staging environment for heroku app

I am coming in late to add some functionality to an already existing app hosted on heroku. The original builder has given me access and I 'heroku git:clone -a app-name' to my local computer.
I've found some conflicting instructions on how to set up a staging environment for this site. I don't want to push to the original site but want a way to try out functionality.
If anyone has had experience with staging and heroku, I'd appreciate any clarification.
You'll need to create a staging.rb file in config/environments. You can copy development.rb or production.rb and adjust whatever values you need.
Heroku will handle configuring the database configuration and such. You can clone an app in Heroku or just create a new one, then set it's RAILS_ENV and RACK_ENV environment variables to staging, and push to it.
Please refer: Heroku - Managing Multiple Environments for an App
You Need to create a second Heroku application that hosts your staging application.
Follow the instructions provided in the link for working with multiple environment in heroku.

Rails 4.2 capistrano 3 deployment

I am totally new to rails deployment. After googling, I still find it hard to understand how to deploy rails apps.
So, my questions are:
After setting up the VPS with all rails dependencies, where do I store my codebase? The root directory of the VPS or some specific locations e.g. www/ or public/?
Should I upload the whole rails app folder or just part of it? I have paperclip in my rails app, and paperclip creates a system/ directory in the public/ folder, so should I upload system/?
In Capistrano 3, there is a repo_url field, I know they support file://, https://, ssh://, or svn+ssh://, but most of the articles about capistrano put github repositories into that. However, I do not have such a github repo. What should I input then?
Thank you for your attention.
Answers to the specific questions raised:
After setting up the VPS with all rails dependencies, where do I store
my codebase? The root directory of the VPS or some specific locations
e.g. www/ or public/?
It will be deployed to the folder pointed by :deploy_to parameter. If not specified, :deploy_to defaults to /var/www/#{fetch(:application) See: https://github.com/capistrano/capistrano/blob/05f63f5f333bb261f2a4c4497174361c48143252/lib/capistrano/defaults.rb#L3
Should I upload the whole rails app folder or just part of it? I have
paperclip in my rails app, and paperclip creates a system/ directory
in the public/ folder, so should I upload system/?
Paperclip system folder is specific to the environment; each environment (development, production,...) will have its own system folder which will store the files uploaded on that specific environment. This folder should not be part of the code being deployed.
The recommended way of handing such folders is the keep them in a shared folder on the server, and create symlinks in the current version of the code so that the same folder is used for storing/retrieving attachments. See Section 3. Update custom links section in http://robmclarty.com/blog/how-to-deploy-a-rails-4-app-with-git-and-capistrano for more details about this.
As mentioned there, the same applies to config/database.yml file, and any other file containing environment specific configurations.
In Capistrano 3, there is a repo_url field, I know they support
file://, https://, ssh://, or svn+ssh://, but most of the articles
about capistrano put github repositories into that. However, I do not
have such a github repo. What should I input then?
Depends on where the code you are deploying is stored. If it is in a local folder, use the file::// format to specify where the files are located.
You can set up your own private git server, then in deploy.rb you can put something like
set :repo_url, 'ssh://user#server_ip/path/to/your_git_repo.git'
When you commit your changes to the git repo, you do not have to upload the app to the server. Capistrano will upload the app for you when you deploy.
where do i put my code base? This is determined by what you put in deploy.rb e.g
set :deploy_to, '/path/to/my_codebase'
Whether to upload the /system directory will depend on whether you want the paperclip images on your version control. If not you can add the directory to gitignore. Here is a tutorial on how to deploy on ubuntu 14.04 passenger and NGINX. if you are not using Passenger and Nginx you can skip to how to configure capistrano and make adjustments depending on your setup.
EDIT
You need to install git on your development machine and set up a git server on your VPS as explained on the link above, add your remote server to your local machine using
git remote add origin <server>
where 'server' is the url to your git repo in the VPS e.g.
ssh://VPS_user#VPS_ip/path/to/your_git_repo.git
Now when you commit and push your changes to the server, capistrano will deploy the latest version on your git server.
Here is a link with a guide on how to get started with git

What is the best workflow for updating / deploying a Rails app through Git?

I just deployed my first Ruby on Rails app on a VPS at Digital Ocean.
To get started quickly, I did this by simply dragging my Rails directory tree (and its containing files) onto the server via (S)FTP.
I know this isn't the best solution in the long run. So how can I link my app on the server to my git repository at GitHub?
Ideally, when I work on my app locally, and then git commit and git push to my git repository, my app on the VPS will also get updated automatically.
How can this be achieved or what is the best strategy to achieve this?
Since I am building this app just by myself, I can probably keep things simple and stick to a single master branch, rather than having multiple branches.
Thanks for any help.
If I were you, I'd do the pulling and updating on the remote manually. Sorry, but this is not only best practice, but will also force you to learn something useful about system administration and don't require you to be dependent on one host, but can switch service provider and setup as easy it is to make a git-clone somewhere else.
So my workflow would be:
Client:
# Do some changes, commit and add a nice message
$ git commit myfiles
# Push to remote once I'm happy.
$ git push
# SSH to server, and continue from there.
$ ssh username#server
Server:
# Enter project directory
$ cd /var/www/myproject
# Pull code
$ git pull
Done. Or perhaps finish by refreshing server container (uWSGI, fcgi, gunicorn, what have you...)
Reading other similar answers, they hint to looking at the following resource using Capistrano:
Capistrano documentation at GitHub
You should spend a little time now setting up deploys with some automation. Since you are using rails, you should try Capistrano Gem
Capistrano will help you deploy and maintain your application with just a few simple commands. The Readme will show you how to get started, but in general, you will add the Gem by adding this to your Gemfile:
gem 'capistrano', '~> 3.2.0'
then run bundle install to install Capistrano into your bundle. If you are not already using bundler, you should start.
then run bundle exec cap install to setup your local repo for Capistrano.
Basically now you have a nice structure for deployment scripts as part of your repo. You will have to write some deploy scripts now, or modify the examples.
Once done, Capistrano will help you deploy new code (once committed and pushed to your remote repo) and restart the services.
It depends on whatever service you are using to publish your app. Depending on the provider, they may or may not provide rails service. For example, a site like Heroku, where you can actually host for free up until certain restrictions is accessible via github and you can do exactly what you're saying and just push up and publish.
If you can put your repo on your server, you can set up post-receive hooks to pull your branch into your web app directory.
To do so you would create a bare repo on your server, add it as a remote on your development machine, and then (on your server) create the file /my/app.git/hooks/post-receive and add these lines:
#!/bin/bash
#CONFIG
LIVE="/home/saintsjd/www"
read oldrev newrev refname
if [ $refname = "refs/heads/master" ]; then
echo "===== DEPLOYING TO LIVE SITE ====="
unset GIT_DIR
cd $LIVE
git pull origin master
echo "===== DONE ====="
fi
Code from Automated Deployment of PHP Applications using git, by Jon Saints.
Note that it would be possible to do something like this without putting the repo on your server if you use Github's webhooks (https://developer.github.com/v3/repos/hooks/).
However, I would highly recommend using Capistrano (https://github.com/capistrano/capistrano), which can deploy your application code and help you with a lot of administrative tasks (like restarting the server, etc.).
If you want to stick relatively close to git, you might also check out the git-deploy gem.

ROR deployment: Staging and Development environments

I already have a production instance deployed on the server. Its working well.
Here is what I need to do.
Deploy a staging and Development environment on the server.
I have already created a branch in github to do that.
Config
1) Ruby 1.8.6
2) Rails is being vendored
3) Webserver Nginx and Thin
4) I have already create a file under /usr/local/nginx/sites-enabled and sites-available folders
5) Added yml file under /etc/thin
6) Made edits to the deploy.rb and have added dev.rb under the config and deploy folders
7) Capistrano is being used on the server for deploy
Questions:
How to deploy the dev environment from separate github branch different that production ? Will that reboot/affect the current production environment too ?
I want to make sure the production wont get affected by this. Please provide a list of commands
or tutorials that will help me with this. I am into very early stages of of learning ROR so please be
a little details. Help is very much appreciated.
EDIT:
1) Capify the project by installing the gem locally and running capify locally.
2) Make changes to you deploy.rb under config
3) set :stages with staging and production
4) set :default_stage as staging .. You have to edit this file more to customize your deployment
5) Under config/deploy/ : Create you production and staging ".rb" files. set the branch to master or any specific branch. Set your rails_env to staging in staging.rb and to production in production.rb.
Set deploy_to as xxxpath/staging and xxxpath/production in those appropriate files.
6) cap deploy will deploy in staging as default due to 4)
7) cap production deploy for production
It looks like you're most of the way there. The key will be to ensure that Capistrano deploys each branch to a separate location on the filesystem -- the sites-available document roots should be different (in other words, don't overwrite your production files!).
Two methods, if you have set stable production, staging and development branches, use the method documented here http://help.github.com/deploy-with-capistrano/
You can use this method for one-off branch deployments Using capistrano to deploy from different git branches.
Passenger looks for the file tmp/restart.txt to know when to restart; this is under the application tree so should only affect the specific variant of the site.
Depending on your server's capacity, the production site may suffer a brief performance hit from the restart of another environment. When you are able, you should consider getting a separate server for staging, test, dev, etc.

Developing & deploying Rails app from same machine

I have started developing a new Rails app on my server using RVM, Rails 3, & Ruby v1.9.2. I am using Git as my code repository. It's a simple app and I don't want to use an extra server. I just want to deploy my app directly from the same server I am developing on.
I've installed Phusion Passenger w/ Apache to serve my app, but have realized that I can't do that pointing to my development directory as my RAILS_ENV is set to "development". (I found I got file permission errors on the asset pipeline and other issues when I attempted to set RAILS_ENV to "production" and serve the app)
What's the simplest/easiest way to deploy the app? Can I simply:
1) Create a separate user to run rails production (Rails in dev currently runs as me on my Ubuntu server)
2) Clone my repo into a separate dir and configure Apache accordingly
3) Seed my database with the data needed for production (not much data needed here)
4) What else?
I've looked briefly at Capistrano, but it seems like overkill for this simple app. I only need to be able to provide a simple web interface for some data entry. Seems like git push should be sufficient, but I haven't done this before so maybe I'm wrong? Also, if I git push how do I ensure file permissions in the "production" directories are all set properly, particularly for any new files that get created in the originating app directory structure?
Thanks for any ideas.
No- you do not need Capistrano for the above; at this stage I feel it will only serve to confuse you further.
I'd suggest you first save your repo to a private Github or free BitBucket account. What you should do is keep one folder for 'development'.
Remember that Passenger is 'just' a module working with Apache. So what you need to do is setup a virtual host under apache and direct that to another folder on your system. For this example, consider:
~/rails/myapp_development/ and ~/rails/myapp_production/
Passenger always runs the app in production, so that should not be an issue. You can do bundle --without=production in your development setup to ignore any gems listed in the Gemfile under the production namespace, i.e. say you've got the mysql adaptor specified, you can ignore this and have Rails only rely on the SQlite gem.
You can now simply develop in the development folder, commit, push to BitBucket. Deploying will be as simply going into the production folder and doing a git pull and touch tmp/restart.txt.

Resources