/chef-rails

A chef cookbook to deploy a full Ruby on Rails server

Primary LanguageRuby

rails Cookbook

This cookbook is designed to build a server with full configuration for Ruby on Rails applications deployed through Capistrano

The default recipe will install and configure:

  • Configure the sshd with a custom port
  • Install a swap area
  • Nginx, with server configuration for many domains. HTTP requests will redirected on HTTPs
  • Letsencrypt, providing a valid ssl certificate for each domain
  • Postgresql, creating an user for each application and e database for each environment
  • Rbenv, with a specific ruby version for each app environment
  • Nodejs
  • Configure machine users with custom files, sudo access (using cookbook Users)
  • Capistrano directory structure with basic shared folders (log, config) and some secret
  • Supervisord to ensure the puma server is running

Requirements

Platforms

  • Ubuntu 16.04

Chef

  • Chef 12.0 or later

Cookbooks

Add this to your Cheffile in order to install correct versions of cookbooks

cookbook "postgresql",       git: "https://github.com/hbda/chef-postgresql", ref: "rmoriz/pg9.5"
cookbook "capistrano-rails", git: "https://github.com/joeyates/chef-capistrano-rails"
cookbook "users",            git: 'https://bitbucket.org/joeyates/users-cookbook.git'
cookbook "rails"

Attributes

rails::default

Key Type Description Default
['rails']['machine_nane'] String Machine name in ssh banner during login Rails machine
['rails']['sshd']['port'] Integer Ssh port 22
['rails']['swap']['size'] Integer 1024
['rails']['swap']['filepath'] String The path of the swapfile /mnt/swapfile
['rails']['apps_root'] String The directory where applications root will be installed /srv
['rails']['apps_user'] String The application owner "root"
['rails']['extra_packages'] Array Additional packages to install into the machine []
['rails']['apps'] Hash An hash with configuration for the machine (with this you can create all stuffs for many application just running default recipe) true

Usage

Before running the cookbook, if you want to generate an ssl valid certificate with letsencrypt, ensure that your machine is reachable. If you can't do this for now, set

"test_env": true

into "apps" settings in order to use a self signed ssl certificate

"test_env": true

into "apps" settings in order to use a self signed ssl certificate.

Then, you need to create an encrypted data bag with application properties.

bundle exec knife solo data bag create apps rails_app

to create the empty.

Paste the following content into the editor setting variables with your needs

{
  "id": "rails_app",
  "config": {
    "dbpassword": "a_user_db_password",
    "staging": {
      "secret_key_base": "a_secret_value",
      "other_secrets": {
        "a_key": {
          "a_subkey": "a value"
        }
      }
    },
    "production": {
      "secret_key_base": "a_secret_value",
      "other_secrets": {
        "another_key": {
          "another_subkey": "another value"
        }
      }
    }
  }
}

you will find "other_secrets" inside the file

config/secrets.yml

rails::default

{
  "name":"my_node",
  "rails": {
    "machine_name": "My fantastic server",
    "ssh": {
      "port": 1022
    },
    "global_ruby": "2.3.1",
    "apps_user": "deploy",
    "apps": {
      "rails_app": {
        "staging": {
          "ruby_version": "2.3.1",
          "domain": "staging.example.com",
          "aliases": ["staging1.example.com", "staging2.example.com"],
          "admin_email": "admin@example.com",
          "test_env": true
        },
        "production": {
          "ruby_version": "2.3.1",
          "domain": "www.example.com",
          "aliases": ["example.com"],
          "admin_email": "admin@example.com"
        }
      }
    },
    "extra_packages": [
      ["unzip", nil],
      ["nodejs-legacy", nil]
    ]
  },
  "postgresql": {
    "pg_hba_defaults": false,
    "pg_hba": [
      { "type": "local", "db": "all", "user": "postgres", "addr": "",             "method": "peer" },
      { "type": "local", "db": "all", "user": "all",      "addr": "",             "method": "md5" },
      { "type": "host",  "db": "all", "user": "all",      "addr": "127.0.0.1/32", "method": "md5" },
      { "type": "host",  "db": "all", "user": "all",      "addr": "::1/128",      "method": "md5" }
    ]
  },
  "run_list": [
    "recipe[rails]"
  ]
}

Resources/Providers

rails_nginx

Generates configuration files for nginx

Actions
Action Description Default
:install Install an nginx configuration for provided domain true
Attributes
Attribute Description Default value Required
domain The domain to listen nil true
user User that own the nginx configuration files nil true
name The name of nginx configuration nil true
path The root path of the application (directory that contain public) nil false
aliases Additional domain names that redirect to the main domain with 301 [] false
test_ssl If true, used a self signed certifiate generated through amce-staging server false false
admin_email The email address to provide during letsencrypt user registration false
key_path File system path of the private key file you want to use nil true
protocol_policy Specifies what configuration files need to be installed:
  • :only_http - install only configuration for http
  • :only_https - install only configuration for https
  • :both - install both configuration
  • :http_to_https - force all requests through https protocol/li>
  • :https_to_http - force all requests through http protocol/li>
:only_http false
key_path File system path of the private key file you want to use nil true

rails_app

This resource install all the stack (nginx/postgresql/rails directory) for a single environment of an application.

Actions
Action Description Default
:install Install all configuration and directory for a rails application true
Attributes
name The name of nginx configuration nil true
admin_email The email address to provide during letsencrypt user registration false
environment The application environment (staging, production, ecc) nil production
domain The domain to listen nil true
aliases Additional domain names that redirect to the main domain with 301 [] false
user User that own the nginx configuration files nil true
path The root path of the application (directory that contain public) nil false
test_ssl If true, used a self signed certifiate generated through amce-staging server false false
directory Additional directories to create under capistrano shared in addition to log - public directories [] false
protocol_policy Specifies what configuration files need to be installed:
  • :only_http - install only configuration for http
  • :only_https - install only configuration for https
  • :both - install both configuration
  • :http_to_https - force all requests through https protocol/li>
  • :https_to_http - force all requests through http protocol/li>
:only_http false

TODO

  • Support for backup data (database and directories)
  • Multi domain name for a same application (for example a localized application through domain name)
  • Possibility to pass parameters to extra_packages
  • Use supervisord for boot daemon

Contributing

  1. Fork the repository on Github
  2. Create a named feature branch (like add_component_x)
  3. Write your change
  4. Write tests for your change (if applicable)
  5. Run the tests, ensuring they all pass
  6. Submit a Pull Request using Github

License and Authors

Authors:

  • David Librera
  • Joe Yates