Deploying ROR app with Ansible:
Ansible is a lightweight, extensible solution for automating your application provisioning. If you are spending most of the time with the code that manages your infrastructure, not with the infrastructure itself. Any change, regardless how small, would require a considerable amount of effort for a relatively small gain.
With Ansible, there is data describing infrastructure on one hand, and the constraints of the interactions between various components on the other hand. It’s a much simpler model that enables you to move quicker by letting focus on what makes infrastructure personal. Similar to the UNIX model, Ansible provides simple modules with a single responsibility that can be combined in endless ways.
Ansible has no dependencies other than Python and SSH. It doesn’t require any agents to be set up on the remote hosts and it doesn’t leave any traces after it runs either. What’s more, it comes with an extensive, built in library of modules for controlling everything from package managers to cloud providers, to databases and everything else in between.
It allows you to significantly simplify our operations by creating easy YAML-based playbooks. It’s good for configuration automation, deployments and orchestration. And most important – ansible is very easy to learn and also is extremely good with orchestration and rolling deployments.
To add more, We can also Automate our Ruby on Rails server configuration with ansible. Tools like railsbox helps us to start applying best practices on DevOps Solutions in our project by generating ansible playbooks for configuring and deploying Ruby on Rails applications. We no longer need to edit a single configuration file on your server and use tools like capistrano for code deployments – all this comes out of the box.
Ansible rails deployment also handles some additional setup which might be required:
>> It takes care of a proper $GEM_HOME and $PATH setup. This is important because all necessary binaries (bundle, gem, …) need to be locatable using $PATH, otherwise Ansible won’t find the binaries.
>> Then it makes sure that all necessary folders exists, like {{ deploy_to }}, {{ deploy_to }}/shared, {{ deploy_to }}/releases, and all other folders you might need. This can be adjusted using the directoriesvariable.
>> It ensures all configuration files exists & are up to date. This step uses Ansible’s template directive and can be configured using the templates variable.
>> Now that the pre-requirements are met, a bare copy of your git repository is created or updated, and then cloned into a separate build directory.
>> A production bundle is created to make sure that all production dependencies are installed properly.
>> The database is migrated and the assets are generated. Both steps are configurable using the migrate and compile_assets variable, and default to true
>> If all prior steps succeeded, the deployment is considered a success, and the current symlink is updated to the new location.
>> Lastly, old versions of your code are removed. only the 5 most recent versions are kept.
The application restart needs to be handled in a separate role, which you write yourself, because ansible does not support dynamic handler invocation.
Deploying ROR app with Docker?
Docker is establishing itself as the most reliable and convenient way of deploying a process on a host. This can be anything from mysqld to redis, to a Rails application. Just like git snapshots distributes code in the most efficient way, Docker does the same with processes. It guarantees that everything required running that process will be available regardless of the host that it runs on.
Docker and application dependencies:
Most programmer are specific about the version of the programming language which their application needs, the version of the dependencies in the form of Python packages, Ruby gems or node.js modules, but when it comes to something as important as the database or the message queue, they just use whatever is available in the environment that the application runs, but this is one of the reasons behind the devops movement, developers taking responsibility for the application’s environment. Docker makes this task easier and more straightforward by adding a layer of pragmatism and confidence to the existing practices.
For a medium-sized Rails application, with about 100 gems and just as many integration tests running under Rails, this takes 8 minutes and 16 seconds on a 2GB and 2 core instance, without any local Docker images. If you already had Ruby, MySQL & Redis Docker images on that host, this would take 4 minutes and 45 seconds. Furthermore, if you had a master application image to base a new Docker image build of the same application, this would take a mere 2 minutes and 23 seconds. To put this into perspective, it takes just over 2 minutes to deploy a new version of Rails application, including dependent services such as MySQL and Redis.
Ansible gives the joy of managing infrastructures. Docker gives you confidence and stability when dealing with the most important step of application development, the delivery phase. In combination, they are unmatched.
Most deployments consist of only three steps:
>> Checking out a new version of your application.
>> Applying changes to your environment such as, database migrations, assets.
>> Restarting the app server to pick up code changes.
Depending on your app every step can involve some complex operations, like zero downtime deployments with dropped database columns in between. These more complex problems require special handling and you need to take care of this.
Why not Capistrano ?
Capistrano is a command line app for rolling out web app to multiple server. It has been developed for ROR app in the first place, but it works just as well for apps of all kind. It is a work horse but one of its main problems is it’s slow. A simple rails app that didn’t have to run any migrations or precompiled new assets would routinely take 60 seconds on an ec2 micro instance. The same app can be deployed using Ansible in 10 seconds and it can also be trimmed down to 3 seconds with more aggressive checks to determine if certain actions need to happen.
Capistrano nothing but another tool that you need to learn and maintain. If you don’t want to use a tool to provision your infrastructure and then use another tool to deploy applications and also if you don’t want to keep track of your infrastructure in 2 places or have to write custom tooling to glue both tools together in a way that half way works and is brittle. Fortunately Ansible is created to solve this exact issue.
The deploy process is overly complicated. You don’t need the concept of a “current” release, a bunch of symlinks and rollbacks. Rollbacks should be handled by fixing your code or just simply rollback your code in git and deploy the last working version.