Rails 4.2 capistrano 3 deployment - ruby-on-rails

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

Related

Folder contents are automatically deleted every time I deploy my Rails app

I have a directory under /public folder with the use of CarrierWave I store all my PDF files under this dir. But the problem is all the time I deploy new version of my Rails app this directory gets cleaned up and the all files are missing. This directory is was set under my uploader.
I also have a directory named "private" which I created manually in order to not to serve sensitive files globally on WEB. Those files also gone after new deployment process.
How can I prevent files from deleting on deploy process?
Thanks.
I assume you are using some automation for deployment. Because if you are updating your code on server instance manually then you can preserve pre uploaded file, but using manually method to update code is not a good practice.
So in automation deployment we generally follow this kind of flow.
Whenever you deploy that create a new deploy version and set that as current version.
Simply that means it's creating a new directory and placing your rails project in it. Now the files you are storing inside the project directory are there in the previous version those are not gone if you are using any linux instance.(Only if you have setup that way to preserve last few versions to restore incase of new deploy is exploded)
Clear till now?
Not suppose you are not keeping any previous version, your files are gone forever.
So it's not a good idea to store any file under project repository.
Best practice is to use bucket system like AWS bucket or Google cloud bucket, where we store all the uploaded file. If having bucket is not in budget, you can choose a different directory on linux server instance outside of project directory. But you have to setup all those upload paths and directory system to be used as bucket.
This problem I am facing with is happening because of capistrano. Every time I run cap production deploy command on my server, the capistrano deployment tool syncs every file with git repo. And the files added by end-users are not stored under my git repos of course, so capistrano overwriting the empty public folder from my repo to the server. Adding the path to :linked_dirs variable under deploy.rb solved my problem.
Another approach could be using a directory which is somewhere else than your project root path (such as /home/files) to store all your files. By doing this you will be seperating your files from project and also prevent capistrano's overwriting problem.
Hope this information will be useful for someone or future me :) ..
When you deploy with capistrano, a new deploy(folder) is created from the repository.
Any files not in the repository are not carried over.
If you want to persist files in public, you need to create a directory in your server first and then create a symlink with capistrano inside public to that folder.
Then have your carrierwave uploads saved to that location.
During each deployment cap will symlink to that directory and your files will be there

How to share folders across deploys

I'm using Amazon Elastic Beanstalk for my Rails application.
My Rails application generates pdf-documents, that are stored in public/posters.
When I deploying commit in question, all files from public folder are replaced by files from deployed commit.
I other words, I'm loosing all the user-generated data after commit.
How to configure my app or AWS to make some folders shared between commits, to prevent deletion?
Thanks!
If you use capistrano, you can use shared_children option.
set :shared_children, %w(public/posters log tmp/pids)
Otherwise you can setup symbol link.
make shared directory for posters
add public/posters in .gitignore
make symbol link public/posters to shared/posters

Rails untracked files to Heroku server

I am trying to deploy a rails app to heroku, and I know that their file system is read only, and it only contains the latest code. I am using a git repository, via this guide. I have a config file, holding passwords and other stuff that I don't want to track on git, but I have to upload them to heroku. How can I accomplish that?
Rather than store the confidential info in the app files, set them up as environment variables on heroku using config vars
Ref: https://stackoverflow.com/a/7832040/429758

From manual pull on server to Capistrano

I've always deployed my apps through SSH by manually logging in and running git pull origin master, running migrations and pre-compiling assets.
Now i started to get more interested in Capistrano so i gave it a try, i setup a recipe with the repository pointing to github and deploy_to to /home/myusername/apps/greatapp
The current app on the server is already hooked up with Git too so i didn't know why i had to specify the github url in the recipe again, but i ran cap deploy which was successful.
The changes didn't apply, so out of curiosity i browsed to the app folder on the server and found out that Capistrano created folders: shared, releases and current. the latter contained the app, so now i have 2 copies one in /home/myusername/apps/greatapp and another in /home/myusername/apps/greatapp/current.
Is this how it should be? and I have to migrate user uploads to current and destroy the old app?
Does Capistrano pull the repo on my localhost then upload it through SSH or run pull on the server? in other words can someone outline how the deployment works?
Does Capistrano run precompile:assets?
/releases/ is for previous versions incase you want to do cap:rollback.
/current/ as you rightly pointed out is for the current version of your app.
/shared/ is for files and folders that you want to persist between deployments, they typically get symlinked to your /current/ folder as part of your recipe.
Capistrano connects to your server in a shell and then executes the git commands on the server.
Capistrano should automatically put anything in public/system (the rails convention for stored user-uploaded files) into the shared directory, and set up the necessary symlinks.
If you put in the github url, it actually fetches from your github repo. Read https://help.github.com/articles/deploying-with-capistrano for more info.
It does, by default.

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