CentOS 6.5 Puppet v3 Nginx Unicorn and God 1

This article describes to install Puppet 3.x with Nginx 1.x and Unicorn.
God is used to monitor start and stop Unicorn.
It is based on the article on http://projects.puppetlabs.com/projects/1/wiki/using_unicorn

Version numbers may change, it depends on versions available in the repositories.
Another article will be written to describe a solution for managing local repositories in DTAP.

This is based on a machine with the FQDN puppet-master.localdomain, if your hostname is different change the filename of the certificates.

On CentOs additional repositories are needed for installing Puppet 3.x, the puppetlabs and epel repository.

yum -y install http://yum.puppetlabs.com/el/6/products/x86_64/puppetlabs-release-6-7.noarch.rpm
yum -y install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

Install the puppet server including all depencies

yum -y install puppet-server

Start the puppet and start and stop the puppetmaster.
The start/stop of the puppetmaster make sure the CA certificates are created.

puppet resource service puppet ensure=running enable=true service puppetmaster start service puppetmaster stop

Create an Nginx/Unicorn environment for puppet.

yum -y install nginx rubygems make gcc ruby-devel
gem install rack
gem install unicorn
gem install god

Check the installed gems.

gem list
*** LOCAL GEMS ***
  god (0.13.3)
  json (1.5.5)
  kgio (2.8.1)
  rack (1.5.2)
  raindrops (0.12.0)
  unicorn (4.7.0)

Copy the Puppet ruby configuration

cp /usr/share/puppet/ext/rack/config.ru /etc/puppet/
chown puppet:puppet /etc/puppet/config.ru

create an /etc/puppet/unicorn.conf with the following content

  worker_processes 8
    working_directory "/etc/puppet"
    listen '/var/run/puppet/puppetmaster_unicorn.sock', :backlog => 512
    timeout 120
    pid "/var/run/puppet/puppetmaster_unicorn.pid"

    preload_app true
    if GC.respond_to?(:copy_on_write_friendly=)
      GC.copy_on_write_friendly = true

    before_fork do |server, worker|
      old_pid = "#{server.config[:pid]}.oldbin"
      if File.exists?(old_pid) && server.pid != old_pid
          Process.kill("QUIT", File.read(old_pid).to_i)
        rescue Errno::ENOENT, Errno::ESRCH
          # someone else did our job for us
chown puppet:puppet /etc/puppet/unicorn.conf
touch /var/log/unicorn_stderr.log
chown puppet:puppet /var/log/unicorn_stderr.log

Test the unicorn configuration.

[root@puppet-master puppet]# unicorn -c /etc/puppet/unicorn.conf
I, [2013-12-18T16:55:36.864664 #4178]  INFO -- : Refreshing Gem list
I, [2013-12-18T16:55:37.482307 #4178]  INFO -- : listening on addr=/var/run/puppet/puppetmaster_unicorn.sock fd=6
I, [2013-12-18T16:55:37.489636 #4185]  INFO -- : worker=1 spawned pid=4185
I, [2013-12-18T16:55:37.490372 #4185]  INFO -- : worker=1 ready
I, [2013-12-18T16:55:37.491053 #4186]  INFO -- : worker=2 spawned pid=4186
I, [2013-12-18T16:55:37.491682 #4186]  INFO -- : worker=2 ready
I, [2013-12-18T16:55:37.492425 #4187]  INFO -- : worker=3 spawned pid=4187
I, [2013-12-18T16:55:37.492969 #4187]  INFO -- : worker=3 ready
I, [2013-12-18T16:55:37.495375 #4184]  INFO -- : worker=0 spawned pid=4184
I, [2013-12-18T16:55:37.496038 #4184]  INFO -- : worker=0 ready
I, [2013-12-18T16:55:37.496592 #4188]  INFO -- : worker=4 spawned pid=4188
I, [2013-12-18T16:55:37.497154 #4188]  INFO -- : worker=4 ready
I, [2013-12-18T16:55:37.497763 #4189]  INFO -- : worker=5 spawned pid=4189
I, [2013-12-18T16:55:37.500436 #4189]  INFO -- : worker=5 ready
I, [2013-12-18T16:55:37.501053 #4190]  INFO -- : worker=6  cheap jersey shirts  spawned pid=4190
I, [2013-12-18T16:55:37.501774 #4190]  INFO -- : worker=6 ready
I, [2013-12-18T16:55:37.503137 #4191]  INFO -- : worker=7 spawned pid=4191
I, [2013-12-18T16:55:37.503863 #4191]  INFO -- : worker=7 ready
I, [2013-12-18T16:55:37.504240 #4178]  INFO -- : master process ready
^CCanceling startup

Create the nginx Unicorn config file.
Create an /etc/nginx/conf.d/puppetmaster.conf

upstream puppetmaster_unicorn {
        server unix:/var/run/puppet/puppetmaster_unicorn.sock fail_timeout=0;

    server {
        listen 8140;

        ssl on;
        ssl_session_timeout 5m;
        ssl_certificate /var/lib/puppet/ssl/certs/puppet-master.localdomain.pem;
        ssl_certificate_key /var/lib/puppet/ssl/private_keys/puppet-master.localdomain.pem;
        ssl_client_certificate /var/lib/puppet/ssl/ca/ca_crt.pem;
        ssl_ciphers SSLv2:-LOW:-EXPORT:RC4+RSA;
        #ssl_verify_client on;
        ssl_verify_client optional;

        root /usr/share/empty;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Client-Verify $ssl_client_verify;
        proxy_set_header X-Client-DN $ssl_client_s_dn;
        proxy_set_header X-SSL-Issuer $ssl_client_i_dn;
        proxy_read_timeout 120;

        location / {
      http://www.cheapnfljerseys4.com         proxy_pass http://puppetmaster_unicorn;
            proxy_redirect off;
touch /var/log/unicorn_puppetmaster.log
chown puppet:puppet /var/log/unicorn_puppetmaster.log

Create an god configuration to let god start unicorn en make sure it wil keep running.
A kind of http://www.wholesalejerseys1.com systemd but than for ruby gems.

mkdir /etc/god

create an /etc/god/puppetmaster.god with the following content

God.watch do |w|
  w.name = "puppetmaster"
  w.interval = 30.seconds
  w.pid_file = "/var/run/puppet/puppetmaster_unicorn.pid"
  w.log = "/var/log/unicorn_puppetmaster.log"
  w.dir = "/etc/puppet"

  w.start = "ulimit -v 750000 && exec /usr/bin/unicorn -c /etc/puppet/unicorn.conf -D"
  w.stop = "kill -QUIT `cat #{w.pid_file}`"
  w.restart = "kill -USR2 `cat #{w.pid_file}`"

  w.start_grace = 10.seconds
  w.restart_grace = 10.seconds

  w.uid = "puppet"
  w.gid = "puppet"


  # determine the state on startup
  w.transition(:init, { true => :up, false => :start }) do |on|
    on.condition(:process_running) do |c|
      c.running = true

  # determine when process has finished starting
  w.transition([:start, :restart], :up) do |on|
    on.condition(:process_running) do |c|
      c.running = true

    # failsafe
    on.condition(:tries) do |c|
      c.times = 5
      c.transition = :start

  # start if process is not running
  w.transition(:up, :start) do |on|

  w.start_if do |start|
    start.condition(:process_running) do |c|
      c.interval = 5.seconds
      c.running = false

Let init start god.
create an /etc/init/god.conf with the following content.

start on stopped rc RUNLEVEL=2345

stop on starting rc RUNLEVEL=[!2345]

env HOME=/etc/puppet

console output
respawn limit 10 120
exec /usr/bin/god --log-level debug -D -c '/etc/god/*.god'

Test proper working of god and unicorn

root@puppet-master puppet]#initctl god
god start/running, process 5291
[root@puppet-master ~]# god status
puppetmaster: init
[root@puppet-master ~]# god status
puppetmaster: init
[root@puppet-master ~]#
[root@puppet-master ~]# god status
puppetmaster: init
[root@puppet-master ~]# god status
puppetmaster: init
[root@puppet-master ~]# god status
puppetmaster: init
[root@puppet-master ~]# god status
puppetmaster: init
[root@puppet-master ~]# god status
puppetmaster: up
[root@puppet-master ~]# god status
puppetmaster: up
[root@puppet-master ~]# ps -eaf | grep unicorn
puppet    5305     1  3 00:42 ?        00:00:00 unicorn master -c /etc/puppet/unicorn.conf -D
puppet    5312  5305  0 00:42 ?        00:00:00 unicorn worker[0] -c /etc/puppet/unicorn.conf -D
puppet    5313  5305  0 00:42 ?        00:00:00 unicorn worker[1] -c /etc/puppet/unicorn.conf -D
puppet    5314  5305  0 00:42 ?        00:00:00 unicorn worker[2] -c /etc/puppet/unicorn.conf -D
puppet    5315  5305  0 00:42 ?        00:00:00 unicorn worker[3] -c /etc/puppet/unicorn.conf -D
puppet    5316  5305  0 00:42 ?        00:00:00 unicorn worker[4] -c /etc/puppet/unicorn.conf -D
puppet    5317  5305  0 00:42 ?        00:00:00 unicorn worker[5] -c /etc/puppet/unicorn.conf -D
puppet    5318  5305  0 00:42 ?        00:00:00 unicorn worker[6] -c /etc/puppet/unicorn.conf -D
puppet    5319  5305  0 00:42 ?        00:00:00 unicorn worker[7] -c /etc/puppet/unicorn.conf -D
root      5337  1366  0 00:42 pts/0    00:00:00 grep unicorn

Start nginx and test puppet.

puppet resource service nginx ensure=running enable=true
[root@puppet-master puppet]# puppet agent --test --server puppet-master.localdomain
Info: Retrieving plugin
Info: Caching catalog for puppet-master.localdomain
Info: Applying configuration version '1390196436'
Notice: Finished catalog run in 0.01 seconds

To check that nginx is used for puppet you can check the /var/log/nginx/access.log log file for log entries.

A test from another server:

root@puppet-master nginx]# puppet ca list --server puppet-master.localdomain

[root@puppet-master nginx]#

[root@theforeman ~]# rm -rf /var/lib/puppet/ssl
[root@theforeman ~]# puppet agent -t --server puppet-master.localdomain
Info: Creating a new SSL key for theforeman.localdomain
Info: Caching certificate for ca
Info: Creating a new SSL certificate request for theforeman.localdomain
Info: Certificate Request fingerprint (SHA256): 08:57:E5:44:0D:8E:0B:17:00:28:FD:E5:BA:50:E9:7F:CC:AE:A5:96:D7:E0:CF:68:1E:80:E6:1C:F8:76:96:C1
Exiting; no certificate found and waitforcert is disabled

[root@puppet-master nginx]# puppet ca sign theforeman.localdomain --server puppet-master.localdomain
Notice: Signed certificate request for theforeman.localdomain
Notice: Removing file Puppet::SSL::CertificateRequest theforeman.localdomain at '/var/lib/puppet/ssl/ca/requests/theforeman.localdomain.pem'
"-----BEGIN CERTIFICATE-----\nMIIFZTCCA02gAwIBAgIBBDANBgkqhkiG9w0BAQsFADAvMS0wKwYDVQQDDCRQdXBw\nZXQgQ0E6IHB1cHBldC1tYXN0ZXIubG9jYWxkb21haW4wHhcNMTQwMTE5MDYwMTU5\nWhcNMTkwMTE5MDYwMTU5WjAhMR8wHQYDVQQDDBZ0aGVmb3JlbWFuLmxvY2FsZG9t\nYWluMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvcl7ukRh0FQom1U/\nVCUKf4sjqB+1b5khgH+aR3GM+oTX7nJo7WsTa21xsv16/fGu3d+B31rYlME7iqYi\nsAX2K1FFbAiuafVQubZehZnHNAErnh2wkjDOFygJsi/gBZirjirusVkf4yL8QVnk\n8jbn4hUUyrkT067Mlh5rRyj28y2ndhqSBiksO9RoMPjomhUIVcFs9W427JIWczuM\n+xlwBmvIrQ54DpxN7ilL4WBQds519qQzJyT0o4DsKGgz9ouTuRjwu37P8aPLjowl\nS05rpQXjdO2wpR9XdUmNCRbNtTE8HXh1iF0ONEJPVm6v7Tn68AUPMsTgdMBqt291\nzaVidMyFU/HXZq8TWVf6VRfn22CoFOaWtuhZ2HQJATt7FtXvcsegdi+MGCShPQUq\nalCHhLJtzoj2SnaB8/UC2M2iBRn3tNbY4tTa1z9wzvzM9b47ni2fOEeebF7WXlf2\nlTN2HxZmEnQ66b51ZcqIOr6xQcz/HHQ1Q0CruSKQXsaTgUMe6BGQl8CqBFkxCZ/J\n4roI3AqOufktJUM3u7w3zyJsci2uG+ZBSfZLEX2IjI1RUFg+xLXQEDfyDN3MvFn8\nvpRIoSrmPo5+tlUs1XCJ3oTuvV+jOWAI6K9ftsZX9JS5lZ6Q3xZJsEutQy8rJKnz\nfOMOwS4892+u0mA6WYjZ1fzg1X0CAwEAAaOBmTCBljA1BglghkgBhvhCAQ0EKFB1\ncHBldCBSdWJ5L09wZW5TU0wgSW50ZXJuYWwgQ2VydGlmaWNhdGUwDgYDVR0PAQH/\nBAQDAgWgMAwGA1UdEwEB/wQCMAAwIAYDVR0lAQH/BBYwFAYIKwYBBQUHAwEGCCsG\nAQUFBwMCMB0GA1UdDgQWBBTjNRF5FNE9WzDrCYRPBXU6t9h1UDANBgkqhkiG9w0B\nAQsFAAOCAgEADRypVgEHc52hOg37vXrQy3fM06l4+uHO1l6VFyU1PO+8cLiEkWas\n7yuCEJWsWJe3+L0iWzgRZ8Re90Dl+OSvYHaQV0NE4fSnZSmDL07sRcsdhQuV/ya0\nqWY8IQthRSHDXGwnnG6emCTM0umzthub6ivRDSzJ46stojz/vVRO0trV+z/pUi4A\n/d6Bf2DPXiqTbwP1O08l9Jh2WGqVo2wegvffPDYcVT0ZIytTNOjofTdeASwXIgzn\nBgB5a1fuqb0DAFzTtDpYdlfrN4pW5oFck6Ty1q/y10wTz538dD9dRvunWQ/j3yxH\nyL4hgMvCjX5JFaHvT8UBWoQPWCSt4Y6eOGagXXG8AYugjiHuVlQqx+ltiZj7YD+O\nm1iNuQVNlh26XRcNRU0usdGfW5sFkQTO2+W7nV5CRd5LYmRg0+rBfy48YoN3IF8G\nSp+Q7o334gqhbCQYl1zQ4EpYBv125TPJ+xx2Nabxi0x0hdSnIKvC19dfDMcalVuG\nnQCq1Hqz1ny4EjnJCUHUYOgF8aGtNsiTTtlp/wt4FaCU5ybB60uzXUD6kF0g+5ul\n/CHqrZhrxPby6DzBEqer2RCbrqNGdupmkxRuIHDjbSv3DnQ0hR074QnIr9f5gYsq\nh2iMZnGzy2UWBuQkE/AD4PvV8dKLpgkS3E/hKLwIQnQ3vmuADwtJyfI=\n-----END CERTIFICATE-----\n"

[root@theforeman ~]# puppet agent -t --server puppet-master.localdomain
Info: Caching certificate for theforeman.localdomain
Info: Caching certificate_revocation_list for ca
Info: Retrieving plugin
Info: Caching catalog for theforeman.localdomain
Info: Applying configuration version '1390197724'
Notice: Finished catalog run in 0.06 seconds
[root@theforeman ~]#

Leave a comment

Your email address will not be published. Required fields are marked *

One thought on “CentOS 6.5 Puppet v3 Nginx Unicorn and God