Configuration

To getting started with a fresh installation you need to prepare your project. The only thing which is needed to do is to create a new deployment structure under a deployment directory under your project root.

To start with a usefull subset of resources, use the example-configuration from the Jity Deployment Service. With the following step you got good base for further usage:

$ ./bin/deployment-console.phar prepare

After this, your project hierarchy should look like this:

.
├── config.yml
├── fixtures
│   ├── demo
│   └── prod
├── hooks
│   ├── archiver
│   │   ├── base
│   │   ├── demo
│   │   │   └── 00_google-keys.sh.dist
│   │   └── prod
│   │       └── 00_google-keys.sh.dist
│   ├── fetcher
│   │   ├── base
│   │   │   ├── git
│   │   │   │   └── 00_composer.sh
│   │   │   ├── local
│   │   │   └── svn
│   │   ├── demo
│   │   │   ├── base
│   │   │   ├── git
│   │   │   ├── local
│   │   │   └── svn
│   │   └── prod
│   │       ├── base
│   │       ├── git
│   │       ├── local
│   │       └── svn
│   └── installer
│       ├── base
│       │   ├── 00_sync.sh
│       │   ├── 10_symfony.sh.dist
│       │   ├── post
│       │   │   ├── 00_varnish.sh.dist
│       │   │   └── 99_cleanup.sh
│       │   └── pre
│       ├── demo
│       │   ├── post
│       │   ├── pre
│       │   └── slaves
│       │       └── slave01.sh.dist
│       └── prod
│           ├── post
│           ├── pre
│           └── slaves
├── logs
├── phing-bridge
│   ├── JityPhingBridge.php
│   └── build.xml.dist
└── tasks
    └── PrepareLocal.php.dist

Note: All *.dist files are ignored by the application. They are there to give you a hint what is possible with this structure. The demo and prod directory represent the various environments you can deploy your application to. There could be an unlimited number of environments with freely chosen names.

The Deployment Configuration File

This file is the head of the whole process. It holds information about where and how we get the source-distribution and where to deploy it to. For that there are many configuration options, but we will only cover the minimal and essential configuration here. So there it is:

# +------------------------------------
# | Deployment Config
# +------------------------------------

deployment:

    slaves:

        demo:

            slave01:
                host: deployment-user@demo.jity.de
                projectDestination: /home/htdocs/demo.jity.de
                packageDestination: /home/htdocs

        prod:

            slave01:
                host: deployment-user@jity.de
                projectDestination: /home/htdocs/jity.de
                packageDestination: /home/htdocs

    packaging:

        fetcher:

            sources:

                local:
                    source:
                        demo:
                            path: .
                        prod:
                            path: .

                git:
                    source:
                        demo:
                            repository: git://gitorious.hermann-mayer.net/jity/jity-deployment.git
                        prod:
                            repository: git://gitorious.hermann-mayer.net/jity/jity-deployment.git

    defaults:
        environment: demo
        source: local

As you can see we annotate two slaves for two different environment. So there is a slave01 for the demo and for the prod environment. We did not explicitly define the names of the environments, they will be parsed adhoc from this configuration. After the configuration is parsed all options will be validated. There will be an error if you annotate an slave for the testing environment and there is no source for this environment. This works mostly the same for the defaults options. If you specify an testing environment as default, and never annotated an slave or/and an source for this there will not throw an error, therefor the first found environment is used as default.

The deployment over the network relies on SSH/SCP with an passwordless publickey authentification.

As an result of the rewrite of the deployment application you can configure mostly all steps which are invoked into the process. There are configuration options for the following steps:

  • Fetcher
  • Fixtures Loader
  • Installer Compiler
  • Archiver

Note

You can get further information to the configuration options with this command:

$ ./bin/deploy-console.phar dump-example-config

If you got highlight installed the output of the configuration will be colored on the commandline.

Options Reference

deployment

The namespace of the configuration.

deployment.slaves
Required
The namespace of all environments/slaves.
deployment.slaves.%environment%

There can an unlimited number of environments be defined under the deployment.slaves namespace. All valid YAML indentifiers can be used.

deployment.slaves.%environment%.host
Required, Valid Syntax: [user@]hostname
The hostname of the slave.
deployment.slaves.%environment%.port
Default: 22
The namespace of all environments/slaves.
deployment.slaves.%environment%.projectDestination
Required
The destination where the the source distribution package will be installed to.
deployment.slaves.%environment%.packageDestination
Required
The destination where the source distribution package will be deployed to.
deployment.packaging
Required
The packaging namespace contains configuration options for all steps of the packaging process.
deployment.packaging.fetcher
Required
The fetcher namespace.
deployment.packaging.fetcher.destination
Default: /tmp/jity-deployment/distribution
The destination where the fetcher will save the source distribution.
deployment.packaging.fetcher.verbose
Default: false
Print output of the fetcher to the console.
deployment.packaging.fetcher.sources
Required
The fetcher sources namespace. Got options for the sources to fetch. One configured fetcher source is needed.
deployment.packaging.fetcher.sources.local

The local fetcher namespace.

deployment.packaging.fetcher.sources.local.extraCliArgs

Pass some extra arguments to the fetcher.

deployment.packaging.fetcher.sources.local.source
Required
If you want to use the local fetcher, you need to configure this namespace.
deployment.packaging.fetcher.sources.local.source.%environment%

You can use all environments you defined for your slaves. The identifiers are the same.

deployment.packaging.fetcher.sources.local.source.%environment%.path
Required, Should be: .
A valid path to the source distribution you want to fetch.
deployment.packaging.fetcher.sources.git

The git fetcher namespace.

deployment.packaging.fetcher.sources.git.extraCliArgs

Pass some extra arguments to the fetcher.

deployment.packaging.fetcher.sources.git.source
Required
If you want to use the git fetcher, you need to configure this namespace.
deployment.packaging.fetcher.sources.git.source.%environment%

You can use all environments you defined for your slaves. The identifiers are the same.

deployment.packaging.fetcher.sources.git.source.%environment%.repository
Required
A valid git repository where to fetch the source distribution from.
deployment.packaging.fetcher.sources.svn

The svn fetcher namespace.

deployment.packaging.fetcher.sources.svn.extraCliArgs

Pass some extra arguments to the fetcher.

deployment.packaging.fetcher.sources.svn.source
Required
If you want to use the svn fetcher, you need to configure this namespace.
deployment.packaging.fetcher.sources.svn.source.%environment%

You can use all environments you defined for your slaves. The identifiers are the same.

deployment.packaging.fetcher.sources.svn.source.%environment%.repository
Required
A valid svn repository where to fetch the source distribution from.
deployment.packaging.fixturesLoader.source
Default: %working.dir%/deployment/fixtures/%environment%
Source path of the fixtures.
deployment.packaging.fixturesLoader.extraCliArgs

Pass some extra arguments to the fixtures loading process.

deployment.packaging.fixturesLoader.verbose
Default: false
Print output of the fixtures loader to the console.
deployment.packaging.installerCompiler.source
Default: %working.dir%/deployment/installer
Source path of the installer partials.
deployment.packaging.installerCompiler.destination
Default: /tmp/jity-deployment
Destination to save the compiled installer scripts.
deployment.packaging.installerCompiler.printUsedPartials
Default: true
Print a statistic of (un)used partials while processing.
deployment.packaging.installerCompiler.validateInstaller
Default: true
Validate the compiled installer script. Should always be enabled.
deployment.packaging.archiver.destination
Default: /tmp/jity-deployment
The destination where the archiver will save the source distribution package.
deployment.packaging.archiver.extraCliArgs

Pass some extra arguments to the package creation process.

deployment.packaging.archiver.format
Available Values: (gzip|bzip2|xz), Default: gzip
Algorithm for the package compression.
deployment.packaging.archiver.verbose
Default: false
Print output of the archiver to the console.
deployment.defaults.environment

Set the default selection for the environment. You can use all environments you defined for your slaves.

deployment.defaults.source

Set the default selection for the fetcher. You can use all your configured fetchers.

deployment.defaults.printUsedCommands
Default: false
Print the commands used for the processes.
deployment.defaults.verboseHooks
Default: false
Print the output of running hooks.

Fixtures

Deployment fixtures are static structures of directories and files which are copied over the original fetched source distribution. Fixtures overwrite already existing files. Here is a simple example to explain the process:

The file deployment/Fixtures/demo/app/config/parameters.yml will be copied over to app/config/parameters.yml if you deploy to the demo environment.

Fixtures are good to easily deploy different versions of a file to different environments. Furthermore you could leave fixtures completely untouched, they are optional to the deployment process.

Hooks

The Jity Deployment is an very flexible application. This is ensured by the hooks-system. Hooks are user-defined scripts which will be executed on a given application event. This means you can just do what you want at a given point, eg. running Composer after the git-fetcher fetched the source-distribution. There are plenty such events. And the best on this feature is the easiness, just write a script, put it in the right place and all is fine. There are three main-hooks: (post)-Fetcher, (pre)-Archiver and (post)-PackageDeployer (named PackageInstaller :). The first both are local hooks while the third is an remote hook. All script which match the current situation and event will be compiled together, validated and executed at the right place. Means local hooks will be executed inside the source-distribution and remote hooks will be executed on the specified server location. To get an better feeling of the hooks, just read on the Installer subsection.

Installer

Installer are hook- and environment-based shell script partials. They are used to build a complete installer script which installs a source-distribution-package on a slave. The structure of the Installer directory works as the Fixtures directory. The demo and prod are the locations for environment-specific partials. However the base directory is an exception to this pattern, it stores all partials which are independent of environments.

An compiled installer script runs the partials in this order:

1. base/pre

2. base

3. environment/pre

4. environment

5. environment/post

6. base/post

7. environment/slaves/slave

To achieve the correct order of multiple partials in an hook or environment of this structure, just name the partials with a starting two digit large number. The compiler will search and find them in this natural order and use them as well.

Another point to mention is the environment/slaves hook. The compiler searches in this directory for a partial which is named like the slave for which the current installer script is build. Say if you configured a slave with the name primary-slave-24 for the prod environment the compiler searches for a primary-slave-24.sh in the directory deployment/Installer/prod/slaves/.

A thumbrule of the installer compiling process is the fact that the compiler just needs one partial to build. Which partial is all the same. So all other partials are just optional. Required is only one. If no partial is found at all, the compiler will throw an exception and this aborts the deployment process.

Note

New: in version 2.0 is the option to let the compiler validate the syntax of the compiled installer script. This prevents errors if everything is deployed to the slaves and an simple typo breaks the deployment process. This validation can be configured, but it is enabled by default.

Note

New: in version 2.0 is the ability to compile a certain installer script for a specified environment/slave to view the result. This can be used with the following command:

$ ./bin/deploy-console.phar dump-installer environment slave

If you got highlight installed the output of the installer script will be colored on the commandline.

Tasks

Tasks are the way to extend the standalone Jity Deployment Application. You can build your own implementations to your project-specific problems with the help of PHP classes. The pattern to build up such a class is very easy, here is an example:

<?php

namespace Task;

use JMS\DiExtraBundle\Annotation as DI;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;

/**
 * PrepareLocal
 *
 * Description.
 *
 * @DI\Service
 * @DI\Tag("jity.deploy.extension.task")
 */
class PrepareLocal extends ContainerAwareCommand
{
    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this
            ->setName('prepare:local')
            ->setDescription('Prepare current environment for development');
    }

    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
    }
}

To get a feeling of how to use this powerfull tool read the Symfony documentation page How to create a Console Command.

Phing Integration

After the preparation of a deployment configuration you can see the deployment/phing-bridge directory. In this directory is a Phing-bridge class to load the Jity Deployment Extension. Also there is a example build.xml.dist which illustrates the usage. This file should be placed at the root of your project.

<?xml version="1.0" encoding="UTF-8"?>

<!--Project Resource-->
<project name="Your Project" default="deploy">

    <taskdef classname="deployment.phing-bridge.JityPhingBridge" name="jity-phing-bridge" />

    <!--Just depend on our service-->
    <target name="deploy">

        <jity-phing-bridge />

        <jity-runtime-inputs />
        <jity-fetcher-inputs />
        <jity-fixtures-loader />
        <jity-installer-compiler />
        <jity-archiver />
        <jity-package-deployer />
        <jity-package-installer />

        <jity-cleanup />

    </target>

</project>

Table Of Contents

Previous topic

Introduction

Next topic

The Application in Pictures

This Page