//
// 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 polymorphic application container.

Karaf can be used as a standalone container, supporting a wide range of applications and technologies.
It also supports the "run anywhere" concept (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[]
