I'm having issues with provisioning a server via Puppet that is compatible with a Capistrano deployment. I'm using puppetlabs/apache to setup my virtualhosts, and it is (rightfully) checking that the docroot
exists (and creating it if it doesn't, ignoring potential nested directory issues). However, the true docroot
will be /var/www/vhosts/${::fqdn}/current/public
, and Capistrano will be creating the appropriate symlink (from current
to releases/{releasestamp}
) when deploying, and is not happy when that directory path is setup by Puppet in advance (due to current
being an actual directory, instead of a symlink, and not being empty).
I've thought about adding something like:
file { "/var/www/vhosts/${::fqdn}/current":
ensure => 'link',
target => '/tmp/initial'
}
and setting up a blank file at /tmp/initial/public/index.html
, so that Capistrano will be able to point current
to the appropriate release when deploying. However, this means that whenever someone re-runs the provision (to apply any configuration changes, for example), the symlink will be relocated to the junk directory (if it even exists at that point).
Any suggestions? I've considered splitting the provision into an application provision and server provision, and having Capistrano execute the application provision when deploying, but I'd really prefer to keep this concise.
You should just use Puppet to create the application directory, and let Capistano take care of creating the releases
and shared
directories using the cap deploy:setup
task, and laying down the current
symlink when deploying a new version with cap deploy
.
In more concrete terms, I recommend having this in your Puppet config:
file { "/var/www/vhosts/${::fqdn}":
ensure => 'directory'
}
Then, as a one-time setup step, run this task to instruct Capistrano to create the releases
and shared
directories within the /var/www/vhosts/${::fqdn}
directory Puppet should have created for you:
cap deploy:setup
And thereafter, simply run cap deploy
to deploy your app, which will create or update the current
symlink for you.
(Note that you can pass the -n
option to cap
to preview the exact commands Capistrano will run, For instance, cap -n deploy:setup
will show the mkdir
commands it runs.)
Puppet's standard Apache module seems to require that docroot
exist, which it does using the following:
# This ensures that the docroot exists
# But enables it to be specified across multiple vhost resources
if ! defined(File[$docroot]) {
file { $docroot:
ensure => directory,
owner => $docroot_owner,
group => $docroot_group,
}
}
But you may be able to disable that using the following:
file { "/var/www/vhosts/${::fqdn}/current/public":
ensure => directory,
replace => false, # don't replace the directory once Capistrano makes it a symlink
}
Just defining the resource yourself may prevent the if ! defined(File[$docroot])
part of the apache::vhost
module from running.