Tired of repetitive, mundane tasks when deploying your Ruby on Rails applications? Manual server updates, code uploads, and configuration changes can drain your development joy. Capistrano, a powerful task automation tool, is here to streamline your deployment process.
This guide builds upon previous knowledge from “Automating Deployments With Capistrano: Getting Started” and “How To Deploy Rails Apps Using Passenger With Nginx on CentOS 6.5.” It will walk you through setting up a robust CentOS server environment with Nginx and Passenger, and then automating deployments using Capistrano.
Prerequisites:
- Familiarity with Git (see DigitalOcean’s Git resources).
- Understanding of basic server administration.
- Prior knowledge of Capistrano (recommended: read the introductory article).
- Knowledge of deploying Rails apps with Passenger and Nginx.
Table of Contents
Glossary
- Capistrano: A Ruby-based automation tool for application deployment.
- CentOS: A Linux distribution used for the deployment server.
- Nginx: A high-performance web server.
- Passenger: A web application server that integrates with Nginx.
- RVM: Ruby Version Manager.
- EPEL: Extra Packages for Enterprise Linux.
- Git: A distributed version control system.
1. Preparing The Deployment Server
1.1 Updating And Preparing The Operating System
- Update system packages:
$ yum -y update - Install development tools:
$ yum groupinstall -y 'development tools' - Add the EPEL repository:
$ sudo su -c 'rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm' - Update again:
$ yum -y update - Install necessary libraries:
$ yum install -y curl-devel nano sqlite-devel libyaml-devel
1.2 Setting Up Ruby Environment and Rails
- Install RVM:
$ curl -L get.rvm.io | bash -s stable - Source RVM:
$ source /etc/profile.d/rvm.sh - Reload RVM:
$ rvm reload - Install Ruby 2.1.0:
$ rvm install 2.1.0 - Install Node.js:
$ yum install -y nodejs - Install Bundler and Rails:
$ gem install bundler rails
1.3 Downloading And Installing App. & HTTP Servers
- Swap Space (if needed):
- Create swap file:
$ sudo dd if=/dev/zero of=/swap bs=1M count=1024 - Format swap file:
$ sudo mkswap /swap - Enable swap:
$ sudo swapon /swap
- Create swap file:
- Phusion Passenger:
- Install Passenger:
$ gem install passenger
- Install Passenger:
- Nginx:
- Compile Nginx with Passenger module:
$ passenger-install-nginx-module(Follow on-screen instructions).
- Compile Nginx with Passenger module:
1.4 Creating The Nginx Management Script
- Create script:
$ nano /etc/rc.d/init.d/nginx - Paste the provided script content.
- Make script executable:
$ chmod +x /etc/rc.d/init.d/nginx
1.5 Configuring Nginx For Application Deployment
- Edit Nginx configuration:
$ nano /opt/nginx/conf/nginx.conf - Add
passenger_app_env development;in thehttpblock (for testing). - Comment out the default
location /block. - Set application root and enable Passenger:
Nginx
root /home/deployer/apps/my_app/public; passenger_enabled on; - Restart Nginx:
$ /etc/init.d/nginx restart - Check Nginx status:
$ /etc/init.d/nginx status
1.6 Downloading And Installing Capistrano
- Install Capistrano:
$ gem install capistrano
1.7 Creating A System User For Deployment
- Add user:
$ adduser deployer - Set password:
$ passwd deployer - Grant sudo privileges:
$ nano /etc/sudoers - Add
deployer ALL=(ALL) ALL.
2. Preparing Rails Applications For Git-Based Capistrano Deployment
2.1 Creating A Basic Ruby-On-Rails Application
- Create application:
$ rails new my_app - Enter directory:
$ cd my_app - Generate scaffold:
$ rails generate scaffold Task title:string note:text - Migrate database:
$ RAILS_ENV=development rake db:migrate - Start server (for testing):
$ rails s
2.2 Creating A Git Repository
- Initialize repository:
$ git init - Add files:
$ git add . - Commit changes:
$ git commit -m "first commit" - Add remote:
$ git remote add origin [email protected]:user123/my_app.git - Generate SSH key:
$ ssh-keygen -t rsa - Add SSH key to GitHub.
- Set Git user info:
$ git config --global user.name "user123"$ git config --global user.email "[email protected]"
- Push to GitHub:
$ git push -u origin master
3. Working With Capistrano To Automate Deployments
3.1 Installing Capistrano Inside The Project Directory
- Install Capistrano files:
$ cap install
3.2 Working With config/deploy.rb Inside The Project Directory
- Edit
config/deploy.rb:$ nano config/deploy.rb - Add application settings:
Ruby
set :application, 'my_app' set :scm, :git set :repo_url, 'https://github.com/user123/my_app.git' set :deploy_to, "/home/deployer/apps/my_app" set :pty, true set :format, :pretty
3.3 Working With config/deploy/production.rb Inside The Project Directory
- Edit
config/deploy/production.rb:$ nano config/deploy/production.rb - Add server settings:
Ruby
role :app, %w{[email protected]} role :web, %w{[email protected]} role :db, %w{[email protected]} server '162.243.74.190', user: 'deployer', roles: %w{web} set :ssh_options, { forward_agent: false, auth_methods: %w(password), password: 'user_deployers_password', user: 'deployer', }
3.4 Deploying To The Production Server
- Deploy:
$ cap production deploy
This single command, executed from your local development machine within your Rails application’s directory, triggers the entire Capistrano deployment process. Here’s what happens behind the scenes:
1. Connection to the Deployment Server:
- SSH Connection: Capistrano uses SSH (Secure Shell) to connect to your production server. The connection details (hostname/IP address, username, password or SSH key) are obtained from the
config/deploy/production.rbfile. - Authentication: Capistrano authenticates using the specified method (password or SSH key). In the provided example, password authentication is used. For better security, SSH keys are strongly recommended.
2. Source Code Retrieval:
- Git Repository Access: Capistrano accesses your application’s source code from the Git repository specified in
config/deploy.rb. - Code Cloning/Updating:
- If this is the first deployment, Capistrano clones the repository to the deployment server.
- For subsequent deployments, it fetches the latest changes from the repository.
- Branch/Tag Selection: Capistrano can be configured to deploy a specific branch or tag. By default, it deploys the
masterbranch.
3. Deployment Process:
- Release Creation: Capistrano creates a new release directory on the server, typically within the
releasesdirectory inside thedeploy_topath. Each release is timestamped, allowing you to easily roll back to previous versions. - Code Deployment: The source code is copied into the new release directory.
- Dependency Installation: Capistrano executes
bundle installto install the required Ruby gems based on your application’sGemfile. - Database Migrations: If your application uses a database, Capistrano can automatically run database migrations using
rake db:migrate. - Asset Precompilation: For Rails applications, Capistrano precompiles assets (CSS, JavaScript) using
rake assets:precompile. - Symbolic Linking: Capistrano creates symbolic links to shared resources (e.g., database configuration files, uploaded files) from the release directory.
- Current Release Update: Capistrano updates the
currentsymbolic link to point to the new release directory, effectively making the new version live.
4. Post-Deployment Tasks:
- Application Restart: Capistrano can be configured to restart your application server (e.g., Passenger, Puma) to load the new code.
- Custom Tasks: You can define custom tasks in your
config/deploy.rbfile to perform any additional actions required for your application, such as clearing caches or running specific scripts. - Cleanup: Capistrano typically cleans up old releases, keeping only a specified number of recent deployments.
In essence, the cap production deploy command automates the following:
- Connecting to your production server.
- Retrieving the latest code.
- Setting up the application in a new release directory.
- Installing dependencies and running necessary tasks.
- Switching the current release to the new version.
- Restarting the application.
This automation significantly reduces the risk of errors and streamlines the deployment process, allowing you to deploy your applications quickly and reliably.