Skip to content
This repository has been archived by the owner on Apr 23, 2019. It is now read-only.

sample_host.json explained

berkes edited this page Dec 23, 2014 · 4 revisions

For the most up-to-date file, please refer to the sample_host.json in master branch

PLEASE NOTE: This wiki-page is under construction and may be outdated or may not cover everything yet.

Below, the file is broken up in parts, each part is documented.

Runlist

  "run_list":["role[mysql]","role[rails_passenger]", "role[sysadmins]"],

In the runlist you define what recipes or roles are ran. In chef-repo, we typically only include roles here.

Available roles are:

  • backup: Set up the server so it makes backups of your apps.
  • base: The base server, will be run by most other recipes or roles.
  • mysql: A databaseserver with MySQL.
  • postgresql: A databaseserver with Postgresql.
  • rails_passenger: Rails App-server with Nginx and Passenger.
  • rails: Rails App-server with Unicorn (incompatible with Rails Passenger).
  • sysadmins: Sets up user-accounts with sudo-access.

MySQL

When the mysql role is in the run-list, you need to provide some basic configuration for the server.

  "mysql": {
    "server_debian_password": "<enter a random password>",
    "server_root_password": "<enter a random password>",
    "server_repl_password": "<enter a random password>"
  },

You need to provide secure root passwords for operations on the database:

  • server_debian_password Sets the password for the special debian-sys-maint user
  • server_root_password Sets the password for the MySQL-root. Be extra carefull with this password.
  • server_repl_password. If provided, this password will be used in a replicating cluster setup. See the README for Mysql for more information.

Package

  "packages": ["<option list of system wide packages>"],

TODO

Sysadmins

When using the sysadmins role in your runlist, you can set the sysadmins's details here.

  "sysadmins": {
    "<username>": {
      "password": "<hashed password: openssl passwd -1 'plaintextpassword'>",
      "ssh_keys": [
        "ssh-rsa AAA123...xyz== foo",
        "ssh-rsa AAA456...uvw== bar"
      ]
    }
  }
  • username: a Unix-compatible username. e.g. alice
  • password: a hashed password for alice. You can hash a password with the command openssl passwd -1 'plaintextpassword' on most Linux and Unix-systems. The password will then be literally plaintextpassword.
  • ssh_keys: A list of public keys which alice uses. If alice has the private key for this public key, she can now log in using this ssh-key. On most systems you can find a public key at $HOME/.ssh/id_rsa.pub.

When running sudo-commands, the user is prompted for the password. When public keys are set up correctly, the user is still prompted for the password in order to run commands as sudo, but the user does not need to provide the password when logging into the server. If the user does not have proper keys set up, the user can log in by providing the password. This is the normal Ubuntu server behaviour wrt sudo.

NOTE: There is not recipe or flag yet, which allows you to remove users. If you remove a user from this list, it will not be removed from the server(s). If you want to deny access, simply change the password and remove the public keys. FRom then on the user can then no longer log into the server. NOTE: This recipe manages the keys, so tools like ssh-copy-id will not work, since the keys they add will be overwritten.

Deploy Keys

  "ssh_deploy_keys": [
    "<enter the contents of an id_rsa.pub here>"
  ],

TODO

Backups

  "backups": {
    "<app_name>_<stage>" : {
      "enabled": true,
      "storage_type": "s3",
      "s3_access_key": "<s3_access_key>",
      "s3_secret_access_key": "<s3_secret_access_key>",
      "s3_bucket": "<s3_bucketname>",
      "s3_region": "<s3_region, i.e.: eu-west-1>",
      "database_type": "<mysql, postgresql or none>",
      "database_username": "<db_username>",
      "database_password": "<db_password>",
      "database_host": "<db_host likely localhost>"
    }
  },

TODO

Applications

  "active_applications": {
    "<appname>_<stage>": {
      "rails_env": "<stage, eg: production>",
      "packages": ["nodejs"],
      "domain_names": ["<domain name>", "<domain name>", "<...>"],
      "ruby_version": "2.1.0",
      "ssl_info": {
        "key": "<ssl key>",
        "crt": "<ssl crt>"
        },
      "env_vars": {
        "key_1": "val_1",
        "key_2": "val_2"
      },
      "database_info": {
        "adapter": "mysql2",
        "host": "localhost",
        "username": "<db username, max 10 characters>",
        "password": "<enter a random password>",
        "database": "<appname>_<stage>"
      }
    }
  }

rails_env

TODO

packages

TODO

domain_names

TODO

Redirect Domains

  "active_applications": {
    "<appname>_<stage>": {
      ...
      "domain_names": ["<domain name>", "<domain name>", "<...>"],
      "redirect_domain_names": ["<domain name>", "<domain name>", "<...>"],
      ...

redirect_domain_names is optional and can be left empty. When it contains domain-names these domains will redirect to the first of the domain_names.

Usefull to redirect from www to non-www or vice versa. Also usefull when you have alternative domains that you want to point to your main domain; rather than serving your app on both domains.

For example:

  domain_names: ['example.com']
  redirect_domain_names: ['www.example.com']

www.example.com will now redirect to example.com

  domain_names: ['example.com', 'example.net']
  redirect_domain_names: ['example.org', 'www.example.org']

example.org and www.example.org will now redirect to example.com. Application can be served on example.com and example.net.

TODO

ruby_version

TODO

nginx_custom

The nginx_custom directive can be used to inject custom nginx configuration at various point in the vhost configuration file.

  "active_applications": {
    "<appname>_<stage>": {
      ...
      "nginx_custom": {
        "before" => "",
        "server_main" => "",
        "server_app" => "",
        "server_ssl" => "",
        "server_ssl_app" => "",
        "upstream" => "",
        "after" => "",
       }

The template is the best reference where these will go. Below is a simplified example for the unicorn-vhost (with upstream) and ssl enabled:

<%= @custom_configuration["before"] %>

server {
  listen 80;
  server_name example.com;
  root /u/app/example_com/current/public;

  try_files $uri/index.html $uri.html $uri @app;

  location @app {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://example_com;
    <%= @custom_configuration["server_app"] %>
  }
  <%= @custom_configuration["server_main"] %>
}

server {
  listen 443 ssl;

  ssl_certificate /u/apps/example_com/shared/config/certificate.crt;
  ssl_certificate_key /u/apps/example_com/shared/config/certificate.key;

  server_name example.com;

  root /u/apps/example_com/current/public;

  location / {
    try_files $uri @app;
  }

  location @app {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto https;
    proxy_redirect off;

    proxy_pass http://explained;
    <%= @custom_configuration["ssl_app"] %>
  }
  <%= @custom_configuration["ssl_main"] %>
}

upstream example_com {
  server unix:/u/apps/example_com/shared/tmp/sockets/unicorn.sock;
  <%= @custom_configuration["upstream"] %>
}

<%= @custom_configuration["after"] %>

Typical uses of the custom places:

  • before: extra server blocks to handle redirects, migrate domains or handle things like "www to non-www redirection"
  • server_app: config options such as options for passenger or the proxy.
  • server_main: include extra configs, such as redirects.
  • ssl_app and ssl_main: same as server_app and server_main, but for SSL. Note: if you set these, but don't have SSL-certificates configured, this block won't be rendered at all; the custom config will not be rendered at all.
  • upstream: directives such as server for load-balancing or fallback servers.
  • after: extra server blocks to handle fallthrough situations or define custom upstream blocks for fallback (e.g. offline-during-migration) situations.

Example

Given a file with redirects in /u/apps/example_com/shared/config/nginx_rewrites.conf containing:

rewrite ^/tags/large-bags$ http://example.com/t/bags break;
rewrite ^/content/about$ http://example.com/t/about-us break;

You can now include that file in the vhost with (note the trailing ;):

  "active_applications": {
    "<appname>_<stage>": {
      ...
      "nginx_custom": {
        "server_main": "include /u/apps/example_com/shared/config/nginx_rewrites.conf;"
       }

Resulting in a vhost:

server {
  listen 80;
  server_name example.com;
  root /u/app/example_com/current/public;

  try_files $uri/index.html $uri.html $uri @app;

  location @app {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://example_com;
  }
  include /u/apps/example_com/shared/config/nginx_rewrites.conf;
}
```

You now have a file where you can maintain custom redirects for
backwards compatibility of an API or for SEO-purposes.


### Troubleshooting
The contents of the custom_conf will be placed in there literally. So,
if you add bogus code, forget a trailing `;` or do something else that
is invalid, the vhost won't be valid anymore and the reload will fail.
On the server, you can investigate `/var/logs/nginx/error.log` which
contains the error.
Nginx will be reloaded (not stopped+started or restarted) which means
the old configuration, the one before the error was introduced and a
reload attempted, will remain active: the server should remain up.
For anything but the most simple directives it is advised to test these
on a test-server; e.g. the Vagrant that ships with chef-repo.


TODO