//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

== Overview

Apache Karaf is a modern and polymorphic container.

Karaf can be used standalone as a container, supporting a wide range of applications and technologies.
It also supports the "run anywhere" (on any machine with Java, cloud, docker images, ...) using the embedded mode.

It's a lightweight, powerful, and enterprise ready platform.

With this flexibility, Karaf is the perfect solution for microservices, systems integration, big data, and much more.

Apache Karaf is powered by OSGi (but you don't need to know what OSGi is to use Karaf).

Apache Karaf uses either the Apache Felix or Eclipse Equinox OSGi frameworks, providing additional features on top of the framework.

Apache Karaf can be scaled from a very lightweight container to a fully featured enterprise service: it's a very flexible and extensible container, covering all the major needs.

Here is a short list of provided features:

* *Hot deployment*: simply drop a file in the `deploy` directory, Apache Karaf will detect the type of the file and
 try to deploy it.
* *Complete Console*: Apache Karaf provides a complete Unix-like console where you can completely manage the container.
* *Dynamic Configuration*: Apache Karaf provides a set of commands focused on managing its own configuration.
 All configuration files are centralized in the `etc` folder. Any change in a configuration file is noticed and reloaded.
* *Advanced Logging System*: Apache Karaf supports all the popular logging frameworks (slf4j, log4j, etc). Whichever
 logging framework you use, Apache Karaf centralizes the configuration in one file.
* *Provisioning*: Apache Karaf supports a large set of URLs where you can install your applications (Maven repository, HTTP,
 file, etc). It also provides the concept of "Karaf Features" which is a way to describe your application.
* *Management*: Apache Karaf is an enterprise-ready container, providing many management indicators and operations
 via JMX.
* *Remote*: Apache Karaf embeds an SSHd server allowing you to use the console remotely. The management layer is also
 accessible remotely.
* *Security*: Apache Karaf provides a complete security framework (based on JAAS), and provides a RBAC (Role-Based Access
 Control) mechanism for console and JMX access.
* *Instances*: multiple instances of Apache Karaf can be managed directly from a main instance (root).
* *OSGi frameworks*: Apache Karaf is not tightly coupled to one OSGi framework. By default, Apache Karaf runs with the Apache Felix
 Framework, but you can easily switch to Equinox (just change one property in a configuration file).

image::karaf.png[]
