# Docker Container

## Getting the image

The first step is pulling the CLI image.

```bash
docker pull keeper/keeper-secrets-manager-cli:latest
```

See the image at <https://hub.docker.com/r/keeper/keeper-secrets-manager-cli>

## Running a container

The next step is running the container. By default the container is setup to run `ksm` in shell mode.

```bash
docker run \
    --rm \
    -it \
    -v $PWD:/wd --workdir /wd \
    -v $HOME/.config:/etc/keeper -e KSM_INI_DIR=/etc/keeper \
    keeper/keeper-secrets-manager-cli:latest
```

1. The docker run command.
2. Flags to remove the container when it is done running. That will prevent a build up of inactive containers.
3. Flag to enable interactions with the container.
4. Mounts the current directory as /wd inside of the container and then set the working directory to /wd inside of the container. This will allow anything written to /wd to be written to the current directory outside of the container. This is useful when downloading a file.
5. Mounts a directory where we want to store, or have, the keeper.ini file. Then we passing the environmental variable telling the CLI where to write or read the keeper.ini file.
6. Name of the image.

## Aliasing

The docker run command can be a little too much to type each time. It is recommend that aliases be created.

```bash
$ alias ksm_shell='docker run --rm -it --workdir $PWD -v $PWD:$PWD -v $HOME/.config:/etc/keeper -e KSM_INI_DIR=/etc/keeper keeper/keeper-secrets-manager-cli:latest'
```

The above will launch the ksm shell.

The next alias is slightly different. At the end of the run command, the application `ksm` is added. This will cause the `ksm` not to start in shell mode.

```bash
$ alias ksm='docker run --rm -it --workdir $PWD -v $PWD:$PWD -v $HOME/.config:/etc/keeper -e KSM_INI_DIR=/etc/keeper keeper/keeper-secrets-manager-cli:latest ksm'
```

## Built-in Binaries

The KSM CLI docker includes a volume mount to both GLIBC (most Linux distributions) and MUSL (Alpine Linux) CLI binaries. The volume is `/cli`. This directory can be mounted into another container using the `volumes_from` in docker-compose or `-v` from command line docker. The ksm executables exists in directory based on the version of C library your Linux distribution is using.

* `/cli/glibc/ksm` - For standard GLIBC distributions like Ubuntu, Debian, Fedora, and CentOS.
* `/cli/musl/ksm` - For Alpine Linux.

For Alpine Linux-based stacks, a dedicated Alpine image is also available at <https://hub.docker.com/r/keeper/keeper-secrets-manager-cli-alpine>

For example, the following is simple framework showing how to access the CLI binary.

```
---
version: "2"
services:
  init:
    image: keeper/keeper-secrets-manager-cli:latest
  main:
    image: ubuntu:latest
    volumes_from:
      - init:ro
    command: [ '/cli/glibc/ksm', 'exec', 'printenv', 'MY_LOGIN' ]
    environment:
      KSM_CONFIG: ewog ... M09IemdQMnc9Igp9
      MY_LOGIN: keeper://bf18xLR3aVut5eYy7oIZZZ/field/login
      LC_ALL: C.UTF-8
      LANG: C.UTF-8
    depends_on:
      init:
        condition: service_completed_successfully
```

The `init` service will load the CLI docker. The container will start, display a CLI splash screen, and then exit. Even though the container has stopped, the `/cli` volume is still accessible.

The `main` service will mount the CLI docker's volume under the directory `/cli` using `volumes_from`. The `command` is overridden to run the GLIBC version of the KSM CLI. The `command` is using the `exec` function of the CLI. That will replace environment variables environment variable, that use the [Keeper Notation](https://docs.keeper.io/en/keeperpam/secrets-manager/about/keeper-notation), with a secret value. The `exec` command, of the CLI, is running the `printenv` application. That will print the environment variable, **MY\_LOGIN**, that has been set to Keeper Notation, and has had its value replaced with a secret by the `exec` command.

```
$ example : docker-compose up
[+] Running 2/0
 ⠿ Container example-init-1  Created                                                                                                                      0.0s
 ⠿ Container example-main-1  Recreated                                                                                                                    0.1s
Attaching to example-init-1, example-main-1
example-init-1  |
example-init-1  | ██╗  ██╗███████╗███╗   ███╗     ██████╗██╗     ██╗
example-init-1  | ██║ ██╔╝██╔════╝████╗ ████║    ██╔════╝██║     ██║
example-init-1  | █████╔╝ ███████╗██╔████╔██║    ██║     ██║     ██║
example-init-1  | ██╔═██╗ ╚════██║██║╚██╔╝██║    ██║     ██║     ██║
example-init-1  | ██║  ██╗███████║██║ ╚═╝ ██║    ╚██████╗███████╗██║
example-init-1  | ╚═╝  ╚═╝╚══════╝╚═╝     ╚═╝     ╚═════╝╚══════╝╚═╝
example-init-1  |
example-init-1  | Current Version: 1.0.13
example-init-1  |
example-init-1  | Running in shell mode. Type 'quit' to exit.
example-init-1  |
example-init-1 exited with code 0
example-main-1  | john.smith@localhost
example-main-1 exited with code 0
```
