diff --git a/slapos/recipe/README.apache.txt b/slapos/recipe/README.apache.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/slapos/recipe/apache/__init__.py b/slapos/recipe/apache/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..506dd97bce7acce465c30eb4a3d048dc4ff265cd
--- /dev/null
+++ b/slapos/recipe/apache/__init__.py
@@ -0,0 +1,201 @@
+##############################################################################
+#
+# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved.
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsibility of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# guarantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 3
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+from slapos.recipe.librecipe import BaseSlapRecipe
+import binascii
+import os
+import pkg_resources
+import hashlib
+import sys
+import zc.buildout
+import zc.recipe.egg
+import ConfigParser
+
+
+class Recipe(BaseSlapRecipe):
+  def getTemplateFilename(self, template_name):
+    return pkg_resources.resource_filename(__name__,
+        'template/%s' % template_name)
+
+  def _install(self):
+    self.path_list = []
+    self.requirements, self.ws = self.egg.working_set()
+    # self.cron_d is a directory, where cron jobs can be registered
+    self.logrotate_d, self.logrotate_backup = self.installLogrotate()
+    self.killpidfromfile = zc.buildout.easy_install.scripts(
+        [('killpidfromfile', __name__ + '.killpidfromfile',
+          'killpidfromfile')], self.ws, sys.executable, self.bin_directory)[0]
+    self.path_list.append(self.killpidfromfile)
+    ca_conf = self.installCertificateAuthority()
+    key, certificate = self.requestCertificate('Login Based Access')
+    apache_conf = dict(
+        apache_login=self.installBackendApache(ip=self.getGlobalIPv6Address(),
+          port=13000, backend=zope_access, key=key, certificate=certificate))
+    self.linkBinary()
+    self.setConnectionDict(dict(
+      site_url=apache_conf['apache_login'],
+    ))
+    return self.path_list
+
+  def installLogrotate(self):
+    """Installs logortate main configuration file and registers its to cron"""
+    logrotate_d = os.path.abspath(os.path.join(self.etc_directory,
+      'logrotate.d'))
+    self._createDirectory(logrotate_d)
+    logrotate_backup = self.createBackupDirectory('logrotate')
+    logrotate_conf = self.createConfigurationFile("logrotate.conf",
+        "include %s" % logrotate_d)
+    logrotate_cron = os.path.join(self.cron_d, 'logrotate')
+    state_file = os.path.join(self.data_root_directory, 'logrotate.status')
+    open(logrotate_cron, 'w').write('0 0 * * * %s -s %s %s' %
+        (self.options['logrotate_binary'], state_file, logrotate_conf))
+    self.path_list.extend([logrotate_d, logrotate_conf, logrotate_cron])
+    return logrotate_d, logrotate_backup
+
+  def registerLogRotation(self, name, log_file_list, postrotate_script):
+    """Register new log rotation requirement"""
+    open(os.path.join(self.logrotate_d, name), 'w').write(
+        self.substituteTemplate(self.getTemplateFilename(
+          'logrotate_entry.in'),
+          dict(file_list=' '.join(['"'+q+'"' for q in log_file_list]),
+            postrotate=postrotate_script, olddir=self.logrotate_backup)))
+
+  def linkBinary(self):
+    """Links binaries to instance's bin directory for easier exposal"""
+    for linkline in self.options.get('link_binary_list', '').splitlines():
+      if not linkline:
+        continue
+      target = linkline.split()
+      if len(target) == 1:
+        target = target[0]
+        path, linkname = os.path.split(target)
+      else:
+        linkname = target[1]
+        target = target[0]
+      link = os.path.join(self.bin_directory, linkname)
+      if os.path.lexists(link):
+        if not os.path.islink(link):
+          raise zc.buildout.UserError(
+              'Target link already %r exists but it is not link' % link)
+        os.unlink(link)
+      os.symlink(target, link)
+      self.logger.debug('Created link %r -> %r' % (link, target))
+      self.path_list.append(link)
+
+  def requestCertificate(self, name):
+    hash = hashlib.sha512(name).hexdigest()
+    key = os.path.join(self.ca_private, hash + self.ca_key_ext)
+    certificate = os.path.join(self.ca_certs, hash + self.ca_crt_ext)
+    parser = ConfigParser.RawConfigParser()
+    parser.add_section('certificate')
+    parser.set('certificate', 'name', name)
+    parser.set('certificate', 'key_file', key)
+    parser.set('certificate', 'certificate_file', certificate)
+    parser.write(open(os.path.join(self.ca_request_dir, hash), 'w'))
+    return key, certificate
+
+  def installCertificateAuthority(self, ca_country_code='XX',
+      ca_email='xx@example.com', ca_state='State', ca_city='City',
+      ca_company='Company'):
+    backup_path = self.createBackupDirectory('ca')
+    self.ca_dir = os.path.join(self.data_root_directory, 'ca')
+    self._createDirectory(self.ca_dir)
+    self.ca_request_dir = os.path.join(self.ca_dir, 'requests')
+    self._createDirectory(self.ca_request_dir)
+    config = dict(ca_dir=self.ca_dir, request_dir=self.ca_request_dir)
+    self.ca_private = os.path.join(self.ca_dir, 'private')
+    self.ca_certs = os.path.join(self.ca_dir, 'certs')
+    self.ca_crl = os.path.join(self.ca_dir, 'crl')
+    self.ca_newcerts = os.path.join(self.ca_dir, 'newcerts')
+    self.ca_key_ext = '.key'
+    self.ca_crt_ext = '.crt'
+    for d in [self.ca_private, self.ca_crl, self.ca_newcerts, self.ca_certs]:
+      self._createDirectory(d)
+    for f in ['crlnumber', 'serial']:
+      if not os.path.exists(os.path.join(self.ca_dir, f)):
+        open(os.path.join(self.ca_dir, f), 'w').write('01')
+    if not os.path.exists(os.path.join(self.ca_dir, 'index.txt')):
+      open(os.path.join(self.ca_dir, 'index.txt'), 'w').write('')
+    openssl_configuration = os.path.join(self.ca_dir, 'openssl.cnf')
+    config.update(
+        working_directory=self.ca_dir,
+        country_code=ca_country_code,
+        state=ca_state,
+        city=ca_city,
+        company=ca_company,
+        email_address=ca_email,
+    )
+    self._writeFile(openssl_configuration, pkg_resources.resource_string(
+      __name__, 'template/openssl.cnf.ca.in') % config)
+    self.path_list.extend(zc.buildout.easy_install.scripts([
+      ('certificate_authority',
+        __name__ + '.certificate_authority', 'runCertificateAuthority')],
+        self.ws, sys.executable, self.wrapper_directory, arguments=[dict(
+          openssl_configuration=openssl_configuration,
+          openssl_binary=self.options['openssl_binary'],
+          certificate=os.path.join(self.ca_dir, 'cacert.pem'),
+          key=os.path.join(self.ca_private, 'cakey.pem'),
+          crl=os.path.join(self.ca_crl),
+          request_dir=self.ca_request_dir
+          )]))
+    # configure backup
+    backup_cron = os.path.join(self.cron_d, 'ca_rdiff_backup')
+    open(backup_cron, 'w').write(
+        '''0 0 * * * %(rdiff_backup)s %(source)s %(destination)s'''%dict(
+          rdiff_backup=self.options['rdiff_backup_binary'],
+          source=self.ca_dir,
+          destination=backup_path))
+    self.path_list.append(backup_cron)
+
+    return dict(
+      ca_certificate=os.path.join(config['ca_dir'], 'cacert.pem'),
+      ca_crl=os.path.join(config['ca_dir'], 'crl'),
+      certificate_authority_path=config['ca_dir']
+    )
+
+  def _getApacheConfigurationDict(self, prefix, ip, port):
+    apache_conf = dict()
+    apache_conf['pid_file'] = os.path.join(self.run_directory,
+        prefix + '.pid')
+    apache_conf['lock_file'] = os.path.join(self.run_directory,
+        prefix + '.lock')
+    apache_conf['ip'] = ip
+    apache_conf['port'] = port
+    apache_conf['server_admin'] = 'admin@'
+    apache_conf['error_log'] = os.path.join(self.log_directory,
+        prefix + '-error.log')
+    apache_conf['access_log'] = os.path.join(self.log_directory,
+        prefix + '-access.log')
+    self.registerLogRotation(prefix, [apache_conf['error_log'],
+      apache_conf['access_log']], self.killpidfromfile + ' ' +
+      apache_conf['pid_file'] + ' SIGUSR1')
+    return apache_conf
+
+  def installFrontendApache(self, ip, port, name, frontend_path, backend_url,
+      backend_path, key, certificate, access_control_string=None):
+    """
+    """
+    pass